qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/26] Block patches
@ 2010-04-23 15:30 Kevin Wolf
  0 siblings, 0 replies; 42+ messages in thread
From: Kevin Wolf @ 2010-04-23 15:30 UTC (permalink / raw)
  To: aliguori; +Cc: kwolf, qemu-devel

Hi Anthony,

this is the first part of the block patches that accumulated in my block branch
during your absence. I consider these patches ready to be merged into master.
I've not included another 13 patches that might still need discussion/review or
depend on such patches. I'm going to send another pull request for them some
time next week.

Kevin

The following changes since commit 6c557ab975fc8e5edb4167a241266c7c4657054a:
  Serge Ziryukin (1):
        audio/sdlaudio: remove unused variable

are available in the git repository at:

  git://repo.or.cz/qemu/kevin.git for-anthony

Bruce Rogers (1):
      Remove un-needed code

Christoph Hellwig (3):
      block: get rid of the BDRV_O_FILE flag
      block: split raw_getlength
      cleanup block driver option handling in vl.c

Kevin Wolf (14):
      qemu-config: qemu_read_config_file() reads the normal config file
      qemu-config: Make qemu_config_parse more generic
      blkdebug: Basic request passthrough
      blkdebug: Inject errors
      Make qemu-config available for tools
      blkdebug: Add events and rules
      qcow2: Trigger blkdebug events
      qcow2: Fix creation of large images
      Replace calls of old bdrv_open
      qcow2: Return 0/-errno in write_l2_entries
      qcow2: Fix error return code in qcow2_alloc_cluster_link_l2
      qcow2: Return 0/-errno in write_l1_entry
      qcow2: Return 0/-errno in l2_allocate
      block.h: bdrv_create2 doesn't exist any more

Stefan Hajnoczi (8):
      block: Do not export bdrv_first
      block: Convert bdrv_first to QTAILQ
      block: Convert first_drv to QLIST
      qemu-img: Eliminate bdrv_new_open() code duplication
      qemu-img: Fix BRDV_O_FLAGS typo
      linux-aio: Fix typo in read() EINTR check
      qcow2: Use QLIST_FOREACH_SAFE macro
      block: Free iovec arrays allocated by multiwrite_merge()

 Makefile.objs          |    6 +-
 block-migration.c      |   63 ++++---
 block.c                |  119 +++++++------
 block.h                |   66 ++++++-
 block/blkdebug.c       |  475 ++++++++++++++++++++++++++++++++++++++++++++++++
 block/qcow2-cluster.c  |   78 +++++---
 block/qcow2-refcount.c |   18 ++
 block/qcow2.c          |   63 +++++--
 block/raw-posix.c      |   65 +++++---
 block/vmdk.c           |    2 +-
 block/vvfat.c          |    5 +-
 block_int.h            |    9 +-
 hw/qdev-properties.c   |   19 ++-
 hw/qdev.h              |    1 -
 hw/virtio-blk.c        |    1 -
 hw/xen_disk.c          |    2 +-
 linux-aio.c            |    2 +-
 monitor.c              |    2 +-
 qemu-config.c          |   48 +++---
 qemu-config.h          |    4 +-
 qemu-img.c             |   93 ++--------
 qemu-io.c              |   28 ++--
 qemu-nbd.c             |    2 +-
 vl.c                   |   82 +++------
 24 files changed, 902 insertions(+), 351 deletions(-)
 create mode 100644 block/blkdebug.c

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

* [Qemu-devel] [PULL 00/26] Block patches
@ 2012-11-14 18:47 Kevin Wolf
  2012-11-19  9:12 ` Kevin Wolf
  0 siblings, 1 reply; 42+ messages in thread
From: Kevin Wolf @ 2012-11-14 18:47 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

The following changes since commit ce34cf72fe508b27a78f83c184142e8d1e6a048a:

  Merge remote-tracking branch 'awilliam/tags/vfio-pci-for-qemu-1.3.0-rc0' into staging (2012-11-14 08:53:40 -0600)

are available in the git repository at:

  git://repo.or.cz/qemu/kevin.git for-anthony

Bharata B Rao (1):
      qemu: Document GlusterFS block driver usage

Gerhard Wiesinger (1):
      vmdk: Fix data corruption bug in WRITE and READ handling

Hervé Poussineau (12):
      fdc-test: split test_media_change() test, so insert part can be reused
      fdc-test: insert media before fuzzing registers
      fdc-test: add tests for non-DMA READ command
      fdc: use status0 field instead of a local variable
      fdc: fix FD_SR0_SEEK for non-DMA transfers and multi sectors transfers
      fdc: fix FD_SR0_SEEK for initial seek on DMA transfers
      fdc: fix false FD_SR0_SEEK
      fdc: implement VERIFY command
      fdc-tests: add tests for VERIFY command
      fdc: remove double affectation of FD_MSR_CMDBUSY flag
      fdc: fix typo in zero constant
      fdc: remove last usage of FD_STATE_SEEK

Kevin Wolf (6):
      qcow2: Fix refcount table size calculation
      qemu-iotests: qcow2: Test growing large refcount table
      fdc: Remove status0 parameter from fdctrl_set_fifo()
      fdc-test: Check READ ID
      megasas: Use bdrv_drain_all instead of qemu_aio_flush
      qemu-io: Use bdrv_drain_all instead of qemu_aio_flush

Nick Thomas (1):
      tests: allow qemu-iotests to be run against nbd backend

Stefan Hajnoczi (4):
      MAINTAINERS: add Stefan Hajnoczi as block and virtio-blk co-maintainer
      aio: switch aiocb_size type int -> size_t
      aio: use g_slice_alloc() for AIOCB pooling
      aio: rename AIOPool to AIOCBInfo

Stefan Weil (1):
      block: Workaround for older versions of MinGW gcc

 MAINTAINERS                      |    2 +
 block.c                          |   31 +++----
 block/blkdebug.c                 |    4 +-
 block/blkverify.c                |    4 +-
 block/curl.c                     |    4 +-
 block/gluster.c                  |    6 +-
 block/iscsi.c                    |   12 +-
 block/linux-aio.c                |    4 +-
 block/qcow2-refcount.c           |    3 +-
 block/qed.c                      |    4 +-
 block/rbd.c                      |    4 +-
 block/sheepdog.c                 |    4 +-
 block/vmdk.c                     |   10 ++-
 block/win32-aio.c                |   14 ++--
 dma-helpers.c                    |    4 +-
 hw/fdc.c                         |  121 +++++++++++++-----------
 hw/ide/core.c                    |    4 +-
 hw/megasas.c                     |    2 +-
 qemu-aio.h                       |   12 +--
 qemu-doc.texi                    |   49 ++++++++++
 qemu-io.c                        |    2 +-
 qemu-options.hx                  |   17 ++++
 tests/fdc-test.c                 |  192 +++++++++++++++++++++++++++++++++++++-
 tests/qemu-iotests/044           |  117 +++++++++++++++++++++++
 tests/qemu-iotests/044.out       |    6 +
 tests/qemu-iotests/common        |   13 ++-
 tests/qemu-iotests/common.config |   10 +-
 tests/qemu-iotests/common.rc     |   23 +++++-
 tests/qemu-iotests/group         |    1 +
 tests/qemu-iotests/iotests.py    |    6 +-
 tests/qemu-iotests/qcow2.py      |    9 +-
 thread-pool.c                    |    4 +-
 32 files changed, 556 insertions(+), 142 deletions(-)
 create mode 100755 tests/qemu-iotests/044
 create mode 100644 tests/qemu-iotests/044.out

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

* Re: [Qemu-devel] [PULL 00/26] Block patches
  2012-11-14 18:47 Kevin Wolf
@ 2012-11-19  9:12 ` Kevin Wolf
  0 siblings, 0 replies; 42+ messages in thread
From: Kevin Wolf @ 2012-11-19  9:12 UTC (permalink / raw)
  To: anthony; +Cc: Kevin Wolf, qemu-devel

Am 14.11.2012 19:47, schrieb Kevin Wolf:
> The following changes since commit ce34cf72fe508b27a78f83c184142e8d1e6a048a:
> 
>   Merge remote-tracking branch 'awilliam/tags/vfio-pci-for-qemu-1.3.0-rc0' into staging (2012-11-14 08:53:40 -0600)
> 
> are available in the git repository at:
> 
>   git://repo.or.cz/qemu/kevin.git for-anthony
> 
> Bharata B Rao (1):
>       qemu: Document GlusterFS block driver usage
> 
> Gerhard Wiesinger (1):
>       vmdk: Fix data corruption bug in WRITE and READ handling
> 
> Hervé Poussineau (12):
>       fdc-test: split test_media_change() test, so insert part can be reused
>       fdc-test: insert media before fuzzing registers
>       fdc-test: add tests for non-DMA READ command
>       fdc: use status0 field instead of a local variable
>       fdc: fix FD_SR0_SEEK for non-DMA transfers and multi sectors transfers
>       fdc: fix FD_SR0_SEEK for initial seek on DMA transfers
>       fdc: fix false FD_SR0_SEEK
>       fdc: implement VERIFY command
>       fdc-tests: add tests for VERIFY command
>       fdc: remove double affectation of FD_MSR_CMDBUSY flag
>       fdc: fix typo in zero constant
>       fdc: remove last usage of FD_STATE_SEEK
> 
> Kevin Wolf (6):
>       qcow2: Fix refcount table size calculation
>       qemu-iotests: qcow2: Test growing large refcount table
>       fdc: Remove status0 parameter from fdctrl_set_fifo()
>       fdc-test: Check READ ID
>       megasas: Use bdrv_drain_all instead of qemu_aio_flush
>       qemu-io: Use bdrv_drain_all instead of qemu_aio_flush
> 
> Nick Thomas (1):
>       tests: allow qemu-iotests to be run against nbd backend
> 
> Stefan Hajnoczi (4):
>       MAINTAINERS: add Stefan Hajnoczi as block and virtio-blk co-maintainer
>       aio: switch aiocb_size type int -> size_t
>       aio: use g_slice_alloc() for AIOCB pooling
>       aio: rename AIOPool to AIOCBInfo
> 
> Stefan Weil (1):
>       block: Workaround for older versions of MinGW gcc
> 
>  MAINTAINERS                      |    2 +
>  block.c                          |   31 +++----
>  block/blkdebug.c                 |    4 +-
>  block/blkverify.c                |    4 +-
>  block/curl.c                     |    4 +-
>  block/gluster.c                  |    6 +-
>  block/iscsi.c                    |   12 +-
>  block/linux-aio.c                |    4 +-
>  block/qcow2-refcount.c           |    3 +-
>  block/qed.c                      |    4 +-
>  block/rbd.c                      |    4 +-
>  block/sheepdog.c                 |    4 +-
>  block/vmdk.c                     |   10 ++-
>  block/win32-aio.c                |   14 ++--
>  dma-helpers.c                    |    4 +-
>  hw/fdc.c                         |  121 +++++++++++++-----------
>  hw/ide/core.c                    |    4 +-
>  hw/megasas.c                     |    2 +-
>  qemu-aio.h                       |   12 +--
>  qemu-doc.texi                    |   49 ++++++++++
>  qemu-io.c                        |    2 +-
>  qemu-options.hx                  |   17 ++++
>  tests/fdc-test.c                 |  192 +++++++++++++++++++++++++++++++++++++-
>  tests/qemu-iotests/044           |  117 +++++++++++++++++++++++
>  tests/qemu-iotests/044.out       |    6 +
>  tests/qemu-iotests/common        |   13 ++-
>  tests/qemu-iotests/common.config |   10 +-
>  tests/qemu-iotests/common.rc     |   23 +++++-
>  tests/qemu-iotests/group         |    1 +
>  tests/qemu-iotests/iotests.py    |    6 +-
>  tests/qemu-iotests/qcow2.py      |    9 +-
>  thread-pool.c                    |    4 +-
>  32 files changed, 556 insertions(+), 142 deletions(-)
>  create mode 100755 tests/qemu-iotests/044
>  create mode 100644 tests/qemu-iotests/044.out

Ping?

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

* [Qemu-devel] [PULL 00/26] Block patches
@ 2013-06-07 11:58 Stefan Hajnoczi
  2013-06-17 21:17 ` Anthony Liguori
  0 siblings, 1 reply; 42+ messages in thread
From: Stefan Hajnoczi @ 2013-06-07 11:58 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori, Stefan Hajnoczi

The following changes since commit 8819c10b5d55d537d59a0ffd5d623f348fc36c47:

  Merge remote-tracking branch 'sstabellini/xen_fixes_20130603' into staging (2013-06-04 14:58:58 -0500)

are available in the git repository at:


  git://github.com/stefanha/qemu.git block

for you to fetch changes up to e73fe2b46c38776288415ce7bc8ba3fcd23721c4:

  hmp: add parameters device and -v for info block (2013-06-07 13:45:01 +0200)

----------------------------------------------------------------
Andreas Färber (1):
      ide: Set BSY bit during FLUSH

Kevin Wolf (19):
      qemu-io: Remove unused args_command
      cutils: Support 'P' and 'E' suffixes in strtosz()
      qemu-io: Make cvtnum() a wrapper around strtosz_suffix()
      qemu-io: Handle cvtnum() errors in 'alloc'
      qemu-io: Don't use global bs in command implementations
      qemu-io: Split off commands to qemu-io-cmds.c
      qemu-io: Factor out qemuio_command
      qemu-io: Move 'help' function
      qemu-io: Move 'quit' function
      qemu-io: Move qemu_strsep() to cutils.c
      qemu-io: Move functions for registering and running commands
      qemu-io: Move command_loop() and friends
      qemu-io: Move remaining helpers from cmd.c
      qemu-io: Interface cleanup
      qemu-io: Use the qemu version for -V
      Make qemu-io commands available in HMP
      blkdebug: Add BLKDBG_FLUSH_TO_OS/DISK events
      ide-test: Add enum value for DEV
      ide-test: Add FLUSH CACHE test case

Stefan Hajnoczi (1):
      blockdev: reset werror/rerror on drive_del

Wenchao Xia (5):
      block: add snapshot info query function bdrv_query_snapshot_info_list()
      block: add image info query function bdrv_query_image_info()
      qmp: add ImageInfo in BlockDeviceInfo used by query-block
      hmp: show ImageInfo in 'info block'
      hmp: add parameters device and -v for info block

 Makefile                   |    2 +-
 Makefile.objs              |    1 +
 block.c                    |    8 +-
 block/blkdebug.c           |    3 +
 block/qapi.c               |  148 +++-
 blockdev.c                 |    4 +
 cmd.c                      |  612 -------------
 cmd.h                      |   79 --
 hmp-commands.hx            |   18 +
 hmp.c                      |   39 +
 hmp.h                      |    1 +
 hw/ide/core.c              |    1 +
 include/block/block.h      |    3 +
 include/block/qapi.h       |   14 +-
 include/qemu-common.h      |    3 +
 include/qemu-io.h          |   46 +
 monitor.c                  |   15 +-
 qapi-schema.json           |   10 +-
 qemu-img.c                 |   20 +-
 qemu-io-cmds.c             | 2118 ++++++++++++++++++++++++++++++++++++++++++++
 qemu-io.c                  | 1990 ++++-------------------------------------
 qmp-commands.hx            |   69 +-
 tests/ide-test.c           |   43 +-
 tests/qemu-iotests/049.out |    8 +-
 util/cutils.c              |   25 +
 25 files changed, 2717 insertions(+), 2563 deletions(-)
 delete mode 100644 cmd.c
 delete mode 100644 cmd.h
 create mode 100644 include/qemu-io.h
 create mode 100644 qemu-io-cmds.c

-- 
1.8.1.4

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

* Re: [Qemu-devel] [PULL 00/26] Block patches
  2013-06-07 11:58 Stefan Hajnoczi
@ 2013-06-17 21:17 ` Anthony Liguori
  0 siblings, 0 replies; 42+ messages in thread
From: Anthony Liguori @ 2013-06-17 21:17 UTC (permalink / raw)
  To: Stefan Hajnoczi, qemu-devel; +Cc: Anthony Liguori

Pulled.  Thanks.

Regards,

Anthony Liguori

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

* [Qemu-devel] [PULL 00/26] Block patches
@ 2013-08-30 14:30 Kevin Wolf
  2013-08-30 17:14 ` Anthony Liguori
  0 siblings, 1 reply; 42+ messages in thread
From: Kevin Wolf @ 2013-08-30 14:30 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

The following changes since commit b5d54bd42158b90b239bb6ce9c13072eb3a53fd2:

  Merge remote-tracking branch 'qemu-kvm/uq/master' into stable-1.5 (2013-08-29 17:21:51 -0500)

are available in the git repository at:


  git://repo.or.cz/qemu/kevin.git for-anthony

for you to fetch changes up to edcbf2869829001b60b15ad32609138ae784a588:

  qemu-iotests: Overlapping cluster allocations (2013-08-30 15:48:59 +0200)

----------------------------------------------------------------
Bharata B Rao (1):
      gluster: Abort on AIO completion failure

Kevin Wolf (6):
      qcow2: Change default for new images to compat=1.1
      block: Remove redundant assertion
      qapi-types.py: Split off generate_struct_fields()
      Revert "block: Disable driver-specific options for 1.6"
      qemu-iotests: Update reference output for 051
      block: Remove old raw driver

Laszlo Ersek (7):
      add skeleton for BSD licensed "raw" BlockDriver
      raw_bsd: emit debug events in bdrv_co_readv() and bdrv_co_writev()
      raw_bsd: add raw_create()
      raw_bsd: introduce "special members"
      raw_bsd: add raw_create_options
      raw_bsd: register bdrv_raw
      switch raw block driver from "raw.o" to "raw_bsd.o"

Max Reitz (11):
      option: Add assigned flag to QEMUOptionParameter
      qcow2-refcount: Snapshot update for zero clusters
      qemu-iotests: Snapshotting zero clusters
      qcow2: Add corrupt bit
      qcow2: Metadata overlap checks
      qcow2: Employ metadata overlap checks
      qcow2-refcount: Move OFLAG_COPIED checks
      qcow2-refcount: Repair OFLAG_COPIED errors
      qcow2-refcount: Repair shared refcount blocks
      qcow2_check: Mark image consistent
      qemu-iotests: Overlapping cluster allocations

Peter Maydell (1):
      block/qcow2.h: Avoid "1LL << 63" (shifts into sign bit)

 block.c                    |   1 -
 block/Makefile.objs        |   2 +-
 block/gluster.c            |  15 +-
 block/qcow2-cache.c        |  17 ++
 block/qcow2-cluster.c      |  25 ++-
 block/qcow2-refcount.c     | 533 ++++++++++++++++++++++++++++++++++++++++-----
 block/qcow2-snapshot.c     |  22 ++
 block/qcow2.c              |  83 ++++++-
 block/qcow2.h              |  53 ++++-
 block/{raw.c => raw_bsd.c} | 170 +++++++--------
 blockdev.c                 | 143 ------------
 docs/specs/qcow2.txt       |   7 +-
 include/block/block.h      |   1 +
 include/monitor/monitor.h  |   1 +
 include/qemu/option.h      |   1 +
 monitor.c                  |   1 +
 scripts/qapi-types.py      |  19 +-
 tests/qemu-iotests/031.out |  12 +-
 tests/qemu-iotests/036.out |   2 +-
 tests/qemu-iotests/051.out |   1 -
 tests/qemu-iotests/060     | 111 ++++++++++
 tests/qemu-iotests/060.out |  44 ++++
 tests/qemu-iotests/062     |  64 ++++++
 tests/qemu-iotests/062.out |   9 +
 tests/qemu-iotests/group   |   4 +-
 util/qemu-option.c         |   9 +
 26 files changed, 1028 insertions(+), 322 deletions(-)
 rename block/{raw.c => raw_bsd.c} (57%)
 create mode 100755 tests/qemu-iotests/060
 create mode 100644 tests/qemu-iotests/060.out
 create mode 100755 tests/qemu-iotests/062
 create mode 100644 tests/qemu-iotests/062.out

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

* Re: [Qemu-devel] [PULL 00/26] Block patches
  2013-08-30 14:30 Kevin Wolf
@ 2013-08-30 17:14 ` Anthony Liguori
  2013-09-02  8:24   ` Kevin Wolf
  0 siblings, 1 reply; 42+ messages in thread
From: Anthony Liguori @ 2013-08-30 17:14 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: qemu-devel

This pull request breaks make check, qemu-system-i386 segvs when
running qtest.  bisect blames the following commit.  I confirmed this
commit introduces the breakage too.

commit 19abade25242079f4b5582de17b2302fe185be2b
Author: Max Reitz <mreitz@redhat.com>
Date:   Fri Aug 30 14:34:29 2013 +0200

    qcow2-refcount: Repair shared refcount blocks

    If the refcount of a refcount block is greater than one, we can at least
    try to repair that problem by duplicating the affected block.

    Signed-off-by: Max Reitz <mreitz@redhat.com>
    Signed-off-by: Kevin Wolf <kwolf@redhat.com>

Backtrace is:

Core was generated by `i386-softmmu/qemu-system-i386 -qtest
unix:/tmp/qtest-30888.sock,nowait -qtest-l'.
Program terminated with signal 11, Segmentation fault.
#0  __strcmp_sse42 () at ../sysdeps/x86_64/multiarch/strcmp.S:259
259    ../sysdeps/x86_64/multiarch/strcmp.S: No such file or directory.
    in ../sysdeps/x86_64/multiarch/strcmp.S
(gdb) bt
#0  __strcmp_sse42 () at ../sysdeps/x86_64/multiarch/strcmp.S:259
#1  0x00002abc7727c395 in get_event_by_name (event=<synthetic pointer>,
    name=0x2abc77e69a96 "flush_to_os")
    at /home/anthony/git/qemu/block/blkdebug.c:195
#2  blkdebug_debug_breakpoint (bs=<optimized out>,
    event=0x2abc77e69a96 "flush_to_os", tag=0x2abc77e69aa2 "A")
    at /home/anthony/git/qemu/block/blkdebug.c:572
#3  0x00002abc773bab84 in break_f (bs=<optimized out>, argc=<optimized out>,
    argv=<optimized out>) at /home/anthony/git/qemu/qemu-io-cmds.c:1938
#4  0x00002abc773be088 in command (argv=0x2abc77e69dc0, argc=3,
    ct=<optimized out>, bs=0x2abc77de35c0)
    at /home/anthony/git/qemu/qemu-io-cmds.c:79
#5  qemuio_command (bs=0x2abc77de35c0, cmd=<optimized out>)
    at /home/anthony/git/qemu/qemu-io-cmds.c:2085
#6  0x00002abc772b8f4d in hmp_qemu_io (mon=0x7fffa0de1110,
    qdict=<optimized out>) at /home/anthony/git/qemu/hmp.c:1510
#7  0x00002abc77469749 in handle_user_command (mon=0x7fffa0de1110,
    cmdline=<optimized out>) at /home/anthony/git/qemu/monitor.c:4005
#8  0x00002abc77469908 in qmp_human_monitor_command (
    command_line=0x2abc77e69a10 "qemu-io ide0-hd0 \"break flush_to_os A\"",
    has_cpu_index=false, cpu_index=<optimized out>, errp=0x7fffa0de11d0)
    at /home/anthony/git/qemu/monitor.c:710
#9  0x00002abc773c29a7 in qmp_marshal_input_human_monitor_command (
---Type <return> to continue, or q <return> to quit---
    mon=<optimized out>, qdict=<optimized out>, ret=0x7fffa0de1240)
    at qmp-marshal.c:1658
#10 0x00002abc774642a0 in qmp_call_cmd (params=0x2abc77e8a370,
    mon=0x2abc77dea430, cmd=<optimized out>)
    at /home/anthony/git/qemu/monitor.c:4506
#11 handle_qmp_command (parser=<optimized out>, tokens=<optimized out>)
    at /home/anthony/git/qemu/monitor.c:4572
#12 0x00002abc774fc2f1 in json_message_process_token (lexer=0x2abc77dea4e0,
    token=0x2abc77e69800, type=JSON_OPERATOR, x=143, y=0)
    at /home/anthony/git/qemu/qobject/json-streamer.c:87
#13 0x00002abc7750ea12 in json_lexer_feed_char (lexer=0x2abc77dea4e0,
    ch=125 '}', flush=false) at /home/anthony/git/qemu/qobject/json-lexer.c:303
#14 0x00002abc7750eba9 in json_lexer_feed (lexer=0x2abc77dea4e0,
    buffer=0x7fffa0de1440 "}nb 0x511\n 0x3\nn ioapic\nNt\"|\274*", size=1)
    at /home/anthony/git/qemu/qobject/json-lexer.c:356
#15 0x00002abc774626fb in monitor_control_read (opaque=<optimized out>,
    buf=<optimized out>, size=<optimized out>)
    at /home/anthony/git/qemu/monitor.c:4593
#16 0x00002abc773b6f87 in qemu_chr_be_write (len=<optimized out>,
    buf=0x7fffa0de1440 "}nb 0x511\n 0x3\nn ioapic\nNt\"|\274*",
    s=0x2abc77ddfbf0) at /home/anthony/git/qemu/qemu-char.c:165
#17 tcp_chr_read (chan=<optimized out>, cond=<optimized out>,
    opaque=0x2abc77ddfbf0) at /home/anthony/git/qemu/qemu-char.c:2509
#18 0x00002abc7840fa5d in g_main_context_dispatch ()
   from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#19 0x00002abc7738a671 in glib_pollfds_poll ()
    at /home/anthony/git/qemu/main-loop.c:189
#20 os_host_main_loop_wait (timeout=<optimized out>)
    at /home/anthony/git/qemu/main-loop.c:234
#21 main_loop_wait (nonblocking=<optimized out>)
    at /home/anthony/git/qemu/main-loop.c:484
#22 0x00002abc77260b9a in main_loop () at /home/anthony/git/qemu/vl.c:2090
#23 main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>)
    at /home/anthony/git/qemu/vl.c:4435
(gdb)

Regards,

Anthony Liguori


On Fri, Aug 30, 2013 at 9:30 AM, Kevin Wolf <kwolf@redhat.com> wrote:
> The following changes since commit b5d54bd42158b90b239bb6ce9c13072eb3a53fd2:
>
>   Merge remote-tracking branch 'qemu-kvm/uq/master' into stable-1.5 (2013-08-29 17:21:51 -0500)
>
> are available in the git repository at:
>
>
>   git://repo.or.cz/qemu/kevin.git for-anthony
>
> for you to fetch changes up to edcbf2869829001b60b15ad32609138ae784a588:
>
>   qemu-iotests: Overlapping cluster allocations (2013-08-30 15:48:59 +0200)
>
> ----------------------------------------------------------------
> Bharata B Rao (1):
>       gluster: Abort on AIO completion failure
>
> Kevin Wolf (6):
>       qcow2: Change default for new images to compat=1.1
>       block: Remove redundant assertion
>       qapi-types.py: Split off generate_struct_fields()
>       Revert "block: Disable driver-specific options for 1.6"
>       qemu-iotests: Update reference output for 051
>       block: Remove old raw driver
>
> Laszlo Ersek (7):
>       add skeleton for BSD licensed "raw" BlockDriver
>       raw_bsd: emit debug events in bdrv_co_readv() and bdrv_co_writev()
>       raw_bsd: add raw_create()
>       raw_bsd: introduce "special members"
>       raw_bsd: add raw_create_options
>       raw_bsd: register bdrv_raw
>       switch raw block driver from "raw.o" to "raw_bsd.o"
>
> Max Reitz (11):
>       option: Add assigned flag to QEMUOptionParameter
>       qcow2-refcount: Snapshot update for zero clusters
>       qemu-iotests: Snapshotting zero clusters
>       qcow2: Add corrupt bit
>       qcow2: Metadata overlap checks
>       qcow2: Employ metadata overlap checks
>       qcow2-refcount: Move OFLAG_COPIED checks
>       qcow2-refcount: Repair OFLAG_COPIED errors
>       qcow2-refcount: Repair shared refcount blocks
>       qcow2_check: Mark image consistent
>       qemu-iotests: Overlapping cluster allocations
>
> Peter Maydell (1):
>       block/qcow2.h: Avoid "1LL << 63" (shifts into sign bit)
>
>  block.c                    |   1 -
>  block/Makefile.objs        |   2 +-
>  block/gluster.c            |  15 +-
>  block/qcow2-cache.c        |  17 ++
>  block/qcow2-cluster.c      |  25 ++-
>  block/qcow2-refcount.c     | 533 ++++++++++++++++++++++++++++++++++++++++-----
>  block/qcow2-snapshot.c     |  22 ++
>  block/qcow2.c              |  83 ++++++-
>  block/qcow2.h              |  53 ++++-
>  block/{raw.c => raw_bsd.c} | 170 +++++++--------
>  blockdev.c                 | 143 ------------
>  docs/specs/qcow2.txt       |   7 +-
>  include/block/block.h      |   1 +
>  include/monitor/monitor.h  |   1 +
>  include/qemu/option.h      |   1 +
>  monitor.c                  |   1 +
>  scripts/qapi-types.py      |  19 +-
>  tests/qemu-iotests/031.out |  12 +-
>  tests/qemu-iotests/036.out |   2 +-
>  tests/qemu-iotests/051.out |   1 -
>  tests/qemu-iotests/060     | 111 ++++++++++
>  tests/qemu-iotests/060.out |  44 ++++
>  tests/qemu-iotests/062     |  64 ++++++
>  tests/qemu-iotests/062.out |   9 +
>  tests/qemu-iotests/group   |   4 +-
>  util/qemu-option.c         |   9 +
>  26 files changed, 1028 insertions(+), 322 deletions(-)
>  rename block/{raw.c => raw_bsd.c} (57%)
>  create mode 100755 tests/qemu-iotests/060
>  create mode 100644 tests/qemu-iotests/060.out
>  create mode 100755 tests/qemu-iotests/062
>  create mode 100644 tests/qemu-iotests/062.out

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

* Re: [Qemu-devel] [PULL 00/26] Block patches
  2013-08-30 17:14 ` Anthony Liguori
@ 2013-09-02  8:24   ` Kevin Wolf
  0 siblings, 0 replies; 42+ messages in thread
From: Kevin Wolf @ 2013-09-02  8:24 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: qemu-devel

Am 30.08.2013 um 19:14 hat Anthony Liguori geschrieben:
> This pull request breaks make check, qemu-system-i386 segvs when
> running qtest.  bisect blames the following commit.  I confirmed this
> commit introduces the breakage too.
> 
> commit 19abade25242079f4b5582de17b2302fe185be2b
> Author: Max Reitz <mreitz@redhat.com>
> Date:   Fri Aug 30 14:34:29 2013 +0200
> 
>     qcow2-refcount: Repair shared refcount blocks
> 
>     If the refcount of a refcount block is greater than one, we can at least
>     try to repair that problem by duplicating the affected block.
> 
>     Signed-off-by: Max Reitz <mreitz@redhat.com>
>     Signed-off-by: Kevin Wolf <kwolf@redhat.com>

Sorry, seems I messed up here. The shell history shows that I did
run 'make check', but somehow the failure must have escaped my
attention (it's not an assertion failure and we do have some noise
in successful runs, maybe that's why)

The other test case that could have caught it (qemu-iotests 026) has
been broken for ages, and we need to finally fix it.

Thanks for catching this, Anthony. I'll send a v2.

Kevin

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

* [Qemu-devel] [PULL 00/26] Block patches
@ 2014-09-05 16:13 Stefan Hajnoczi
  2014-09-05 16:13 ` [Qemu-devel] [PULL 01/26] block: kill tail whitespace in block.c Stefan Hajnoczi
                   ` (26 more replies)
  0 siblings, 27 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2014-09-05 16:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Stefan Hajnoczi

The following changes since commit 30eaca3acdf17d7bcbd1213eb149c02037edfb0b:

  Merge remote-tracking branch 'remotes/spice/tags/pull-spice-20140902-1' into staging (2014-09-02 10:26:10 +0100)

are available in the git repository at:


  git://github.com/stefanha/qemu.git tags/block-pull-request

for you to fetch changes up to 804b985da5f781a2ff0a723c1aae520b9ea95f27:

  ide: Add resize callback to ide/core (2014-09-05 10:38:56 +0100)

----------------------------------------------------------------
Block pull request

----------------------------------------------------------------
Chrysostomos Nanakos (1):
      block/archipelago: Use QEMU atomic builtins

Fam Zheng (2):
      virtio: Import virtio_vring.h
      block: Always compile virtio-blk dataplane

John Snow (5):
      libqos: add a simple first-fit memory allocator
      qtest/ide: Uninitialize PC allocator
      ide: Add wwn support to IDE-ATAPI drive
      IDE: Fill the IDENTIFY request consistently
      ide: Add resize callback to ide/core

Laszlo Ersek (2):
      pflash_cfi01: fixup stale DPRINTF() calls
      pflash_cfi01: write flash contents to bdrv on incoming migration

Liu Yuan (1):
      block: kill tail whitespace in block.c

MORITA Kazutaka (1):
      MAINTAINERS: update sheepdog maintainer

Marc Marí (7):
      tests: Functions bus_foreach and device_find from libqos virtio API
      tests: Add virtio device initialization
      libqos: Added basic virtqueue support to virtio implementation
      libqos: Added indirect descriptor support to virtio implementation
      libqos: Added test case for configuration changes in virtio-blk test
      libqos: Added MSI-X support
      libqos: Added EVENT_IDX support

Peter Lieven (3):
      rename parse_enum_option to qapi_enum_parse and make it public
      qemu-nbd: add option to set detect-zeroes mode
      qemu-nbd: fix indentation and coding style

Stefan Hajnoczi (4):
      qemu-img: clarify src_cache option documentation
      qemu-img: fix rebase src_cache option documentation
      vmdk: fix vmdk_parse_extents() extent_file leaks
      vmdk: fix buf leak in vmdk_parse_extents()

 MAINTAINERS                         |   2 +-
 block.c                             |   2 +-
 block/archipelago.c                 |  76 ++---
 block/vmdk.c                        |   4 +-
 blockdev.c                          |  30 +-
 configure                           |  21 +-
 hw/block/Makefile.objs              |   2 +-
 hw/block/pflash_cfi01.c             |  18 +-
 hw/block/virtio-blk.c               |  20 +-
 hw/ide/core.c                       | 111 +++++--
 hw/net/vhost_net.c                  |   2 +-
 hw/virtio/Makefile.objs             |   2 +-
 include/hw/virtio/dataplane/vring.h |   2 +-
 include/hw/virtio/virtio-blk.h      |   2 -
 include/hw/virtio/virtio_ring.h     | 167 ++++++++++
 include/qapi/util.h                 |  17 +
 linux-headers/linux/vhost.h         |   2 +-
 qapi/Makefile.objs                  |   2 +-
 qapi/qapi-util.c                    |  34 ++
 qemu-img.c                          |   3 +-
 qemu-img.texi                       |   7 +-
 qemu-nbd.c                          | 100 ++++--
 tests/Makefile                      |   3 +-
 tests/ide-test.c                    |   2 +
 tests/libqos/malloc-pc.c            | 280 +++++++++++++++-
 tests/libqos/malloc-pc.h            |   9 +
 tests/libqos/pci.c                  | 111 ++++++-
 tests/libqos/pci.h                  |  10 +
 tests/libqos/virtio-pci.c           | 343 +++++++++++++++++++
 tests/libqos/virtio-pci.h           |  61 ++++
 tests/libqos/virtio.c               | 257 +++++++++++++++
 tests/libqos/virtio.h               | 182 ++++++++++
 tests/libqtest.c                    |  48 +++
 tests/libqtest.h                    |   7 +
 tests/virtio-blk-test.c             | 640 +++++++++++++++++++++++++++++++++++-
 35 files changed, 2368 insertions(+), 211 deletions(-)
 create mode 100644 include/hw/virtio/virtio_ring.h
 create mode 100644 include/qapi/util.h
 create mode 100644 qapi/qapi-util.c
 create mode 100644 tests/libqos/virtio-pci.c
 create mode 100644 tests/libqos/virtio-pci.h
 create mode 100644 tests/libqos/virtio.c
 create mode 100644 tests/libqos/virtio.h

-- 
1.9.3

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

* [Qemu-devel] [PULL 01/26] block: kill tail whitespace in block.c
  2014-09-05 16:13 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
@ 2014-09-05 16:13 ` Stefan Hajnoczi
  2014-09-05 16:13 ` [Qemu-devel] [PULL 02/26] pflash_cfi01: fixup stale DPRINTF() calls Stefan Hajnoczi
                   ` (25 subsequent siblings)
  26 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2014-09-05 16:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf, Peter Maydell, Stefan Hajnoczi, Liu Yuan

From: Liu Yuan <namei.unix@gmail.com>

Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Liu Yuan <namei.unix@gmail.com>
Reviewed-by: Benoît Canet <benoit.canet@nodalink.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 block.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/block.c b/block.c
index cb670fd..d06dd51 100644
--- a/block.c
+++ b/block.c
@@ -2246,7 +2246,7 @@ int bdrv_commit(BlockDriverState *bs)
 
     if (!drv)
         return -ENOMEDIUM;
-    
+
     if (!bs->backing_hd) {
         return -ENOTSUP;
     }
-- 
1.9.3

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

* [Qemu-devel] [PULL 02/26] pflash_cfi01: fixup stale DPRINTF() calls
  2014-09-05 16:13 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
  2014-09-05 16:13 ` [Qemu-devel] [PULL 01/26] block: kill tail whitespace in block.c Stefan Hajnoczi
@ 2014-09-05 16:13 ` Stefan Hajnoczi
  2014-09-05 16:13 ` [Qemu-devel] [PULL 03/26] pflash_cfi01: write flash contents to bdrv on incoming migration Stefan Hajnoczi
                   ` (24 subsequent siblings)
  26 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2014-09-05 16:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Laszlo Ersek, Stefan Hajnoczi

From: Laszlo Ersek <lersek@redhat.com>

Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 hw/block/pflash_cfi01.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index 2238f39..fddef39 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -209,11 +209,11 @@ static uint32_t pflash_devid_query(pflash_t *pfl, hwaddr offset)
     switch (boff & 0xFF) {
     case 0:
         resp = pfl->ident0;
-        DPRINTF("%s: Manufacturer Code %04x\n", __func__, ret);
+        DPRINTF("%s: Manufacturer Code %04x\n", __func__, resp);
         break;
     case 1:
         resp = pfl->ident1;
-        DPRINTF("%s: Device ID Code %04x\n", __func__, ret);
+        DPRINTF("%s: Device ID Code %04x\n", __func__, resp);
         break;
     default:
         DPRINTF("%s: Read Device Information offset=%x\n", __func__,
-- 
1.9.3

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

* [Qemu-devel] [PULL 03/26] pflash_cfi01: write flash contents to bdrv on incoming migration
  2014-09-05 16:13 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
  2014-09-05 16:13 ` [Qemu-devel] [PULL 01/26] block: kill tail whitespace in block.c Stefan Hajnoczi
  2014-09-05 16:13 ` [Qemu-devel] [PULL 02/26] pflash_cfi01: fixup stale DPRINTF() calls Stefan Hajnoczi
@ 2014-09-05 16:13 ` Stefan Hajnoczi
  2014-09-05 16:13 ` [Qemu-devel] [PULL 04/26] virtio: Import virtio_vring.h Stefan Hajnoczi
                   ` (23 subsequent siblings)
  26 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2014-09-05 16:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Laszlo Ersek, Stefan Hajnoczi

From: Laszlo Ersek <lersek@redhat.com>

A drive that backs a pflash device is special:
- it is very small,
- its entire contents are kept in a RAMBlock at all times, covering the
  guest-phys address range that provides the guest's view of the emulated
  flash chip.

The pflash device model keeps the drive (the host-side file) and the
guest-visible flash contents in sync. When migrating the guest, the
guest-visible flash contents (the RAMBlock) is migrated by default, but on
the target host, the drive (the host-side file) remains in full sync with
the RAMBlock only if:
- the source and target hosts share the storage underlying the pflash
  drive,
- or the migration requests full or incremental block migration too, which
  then covers all drives.

Due to the special nature of pflash drives, the following scenario makes
sense as well:
- no full nor incremental block migration, covering all drives, alongside
  the base migration (justified eg. by shared storage for "normal" (big)
  drives),
- non-shared storage for pflash drives.

In this case, currently only those portions of the flash drive are updated
on the target disk that the guest reprograms while running on the target
host.

In order to restore accord, dump the entire flash contents to the bdrv in
a post_load() callback.

- The read-only check follows the other call-sites of pflash_update();
- both "pfl->ro" and pflash_update() reflect / consider the case when
  "pfl->bs" is NULL;
- the total size of the flash device is calculated as in
  pflash_cfi01_realize().

When using shared storage, or requesting full or incremental block
migration along with the normal migration, the patch should incur a
harmless rewrite from the target side.

It is assumed that, on the target host, RAM is loaded ahead of the call to
pflash_post_load().

Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 hw/block/pflash_cfi01.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index fddef39..593fbc5 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -94,10 +94,13 @@ struct pflash_t {
     void *storage;
 };
 
+static int pflash_post_load(void *opaque, int version_id);
+
 static const VMStateDescription vmstate_pflash = {
     .name = "pflash_cfi01",
     .version_id = 1,
     .minimum_version_id = 1,
+    .post_load = pflash_post_load,
     .fields = (VMStateField[]) {
         VMSTATE_UINT8(wcycle, pflash_t),
         VMSTATE_UINT8(cmd, pflash_t),
@@ -982,3 +985,14 @@ MemoryRegion *pflash_cfi01_get_memory(pflash_t *fl)
 {
     return &fl->mem;
 }
+
+static int pflash_post_load(void *opaque, int version_id)
+{
+    pflash_t *pfl = opaque;
+
+    if (!pfl->ro) {
+        DPRINTF("%s: updating bdrv for %s\n", __func__, pfl->name);
+        pflash_update(pfl, 0, pfl->sector_len * pfl->nb_blocs);
+    }
+    return 0;
+}
-- 
1.9.3

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

* [Qemu-devel] [PULL 04/26] virtio: Import virtio_vring.h
  2014-09-05 16:13 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (2 preceding siblings ...)
  2014-09-05 16:13 ` [Qemu-devel] [PULL 03/26] pflash_cfi01: write flash contents to bdrv on incoming migration Stefan Hajnoczi
@ 2014-09-05 16:13 ` Stefan Hajnoczi
  2014-09-05 16:13 ` [Qemu-devel] [PULL 05/26] block: Always compile virtio-blk dataplane Stefan Hajnoczi
                   ` (22 subsequent siblings)
  26 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2014-09-05 16:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Fam Zheng, Stefan Hajnoczi

From: Fam Zheng <famz@redhat.com>

This header has no further dependencies. It only has some stable data
types and primitive functions, so we can copy it to include/hw/virtio in
order to allow vring code (and its user virtio-blk dataplane) to be
built unconditionally, even for cross compiling.

Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 hw/net/vhost_net.c                  |   2 +-
 include/hw/virtio/dataplane/vring.h |   2 +-
 include/hw/virtio/virtio_ring.h     | 167 ++++++++++++++++++++++++++++++++++++
 linux-headers/linux/vhost.h         |   2 +-
 4 files changed, 170 insertions(+), 3 deletions(-)
 create mode 100644 include/hw/virtio/virtio_ring.h

diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index f87c798..a014d21 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -28,7 +28,6 @@
 #include <sys/socket.h>
 #include <linux/kvm.h>
 #include <fcntl.h>
-#include <linux/virtio_ring.h>
 #include <netpacket/packet.h>
 #include <net/ethernet.h>
 #include <net/if.h>
@@ -36,6 +35,7 @@
 
 #include <stdio.h>
 
+#include "hw/virtio/virtio_ring.h"
 #include "hw/virtio/vhost.h"
 #include "hw/virtio/virtio-bus.h"
 
diff --git a/include/hw/virtio/dataplane/vring.h b/include/hw/virtio/dataplane/vring.h
index af73ee2..d3e086a 100644
--- a/include/hw/virtio/dataplane/vring.h
+++ b/include/hw/virtio/dataplane/vring.h
@@ -17,8 +17,8 @@
 #ifndef VRING_H
 #define VRING_H
 
-#include <linux/virtio_ring.h>
 #include "qemu-common.h"
+#include "hw/virtio/virtio_ring.h"
 #include "hw/virtio/virtio.h"
 
 typedef struct {
diff --git a/include/hw/virtio/virtio_ring.h b/include/hw/virtio/virtio_ring.h
new file mode 100644
index 0000000..8f58bc9
--- /dev/null
+++ b/include/hw/virtio/virtio_ring.h
@@ -0,0 +1,167 @@
+#ifndef _LINUX_VIRTIO_RING_H
+#define _LINUX_VIRTIO_RING_H
+/*
+ * This file is copied from /usr/include/linux while converting __uNN types
+ * to uXX_t, __inline__ to inline, and tab to spaces.
+ * */
+
+/* An interface for efficient virtio implementation, currently for use by KVM
+ * and lguest, but hopefully others soon.  Do NOT change this since it will
+ * break existing servers and clients.
+ *
+ * This header is BSD licensed so anyone can use the definitions to implement
+ * compatible drivers/servers.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of IBM nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Copyright Rusty Russell IBM Corporation 2007. */
+
+/* This marks a buffer as continuing via the next field. */
+#define VRING_DESC_F_NEXT   1
+/* This marks a buffer as write-only (otherwise read-only). */
+#define VRING_DESC_F_WRITE  2
+/* This means the buffer contains a list of buffer descriptors. */
+#define VRING_DESC_F_INDIRECT   4
+
+/* The Host uses this in used->flags to advise the Guest: don't kick me when
+ * you add a buffer.  It's unreliable, so it's simply an optimization.  Guest
+ * will still kick if it's out of buffers. */
+#define VRING_USED_F_NO_NOTIFY  1
+/* The Guest uses this in avail->flags to advise the Host: don't interrupt me
+ * when you consume a buffer.  It's unreliable, so it's simply an
+ * optimization.  */
+#define VRING_AVAIL_F_NO_INTERRUPT  1
+
+/* We support indirect buffer descriptors */
+#define VIRTIO_RING_F_INDIRECT_DESC 28
+
+/* The Guest publishes the used index for which it expects an interrupt
+ * at the end of the avail ring. Host should ignore the avail->flags field. */
+/* The Host publishes the avail index for which it expects a kick
+ * at the end of the used ring. Guest should ignore the used->flags field. */
+#define VIRTIO_RING_F_EVENT_IDX     29
+
+/* Virtio ring descriptors: 16 bytes.  These can chain together via "next". */
+struct vring_desc {
+    /* Address (guest-physical). */
+    uint64_t addr;
+    /* Length. */
+    uint32_t len;
+    /* The flags as indicated above. */
+    uint16_t flags;
+    /* We chain unused descriptors via this, too */
+    uint16_t next;
+};
+
+struct vring_avail {
+    uint16_t flags;
+    uint16_t idx;
+    uint16_t ring[];
+};
+
+/* u32 is used here for ids for padding reasons. */
+struct vring_used_elem {
+    /* Index of start of used descriptor chain. */
+    uint32_t id;
+    /* Total length of the descriptor chain which was used (written to) */
+    uint32_t len;
+};
+
+struct vring_used {
+    uint16_t flags;
+    uint16_t idx;
+    struct vring_used_elem ring[];
+};
+
+struct vring {
+    unsigned int num;
+
+    struct vring_desc *desc;
+
+    struct vring_avail *avail;
+
+    struct vring_used *used;
+};
+
+/* The standard layout for the ring is a continuous chunk of memory which looks
+ * like this.  We assume num is a power of 2.
+ *
+ * struct vring
+ * {
+ *  // The actual descriptors (16 bytes each)
+ *  struct vring_desc desc[num];
+ *
+ *  // A ring of available descriptor heads with free-running index.
+ *  uint16_t avail_flags;
+ *  uint16_t avail_idx;
+ *  uint16_t available[num];
+ *  uint16_t used_event_idx;
+ *
+ *  // Padding to the next align boundary.
+ *  char pad[];
+ *
+ *  // A ring of used descriptor heads with free-running index.
+ *  uint16_t used_flags;
+ *  uint16_t used_idx;
+ *  struct vring_used_elem used[num];
+ *  uint16_t avail_event_idx;
+ * };
+ */
+/* We publish the used event index at the end of the available ring, and vice
+ * versa. They are at the end for backwards compatibility. */
+#define vring_used_event(vr) ((vr)->avail->ring[(vr)->num])
+#define vring_avail_event(vr) (*(uint16_t *)&(vr)->used->ring[(vr)->num])
+
+static inline void vring_init(struct vring *vr, unsigned int num, void *p,
+                  unsigned long align)
+{
+    vr->num = num;
+    vr->desc = p;
+    vr->avail = p + num*sizeof(struct vring_desc);
+    vr->used = (void *)(((unsigned long)&vr->avail->ring[num] + sizeof(uint16_t)
+        + align-1) & ~(align - 1));
+}
+
+static inline unsigned vring_size(unsigned int num, unsigned long align)
+{
+    return ((sizeof(struct vring_desc) * num + sizeof(uint16_t) * (3 + num)
+         + align - 1) & ~(align - 1))
+        + sizeof(uint16_t) * 3 + sizeof(struct vring_used_elem) * num;
+}
+
+/* The following is used with USED_EVENT_IDX and AVAIL_EVENT_IDX */
+/* Assuming a given event_idx value from the other size, if
+ * we have just incremented index from old to new_idx,
+ * should we trigger an event? */
+static inline int vring_need_event(uint16_t event_idx, uint16_t new_idx, uint16_t old)
+{
+    /* Note: Xen has similar logic for notification hold-off
+     * in include/xen/interface/io/ring.h with req_event and req_prod
+     * corresponding to event_idx + 1 and new_idx respectively.
+     * Note also that req_event and req_prod in Xen start at 1,
+     * event indexes in virtio start at 0. */
+    return (uint16_t)(new_idx - event_idx - 1) < (uint16_t)(new_idx - old);
+}
+
+#endif /* _LINUX_VIRTIO_RING_H */
diff --git a/linux-headers/linux/vhost.h b/linux-headers/linux/vhost.h
index c656f61..bb5df43 100644
--- a/linux-headers/linux/vhost.h
+++ b/linux-headers/linux/vhost.h
@@ -14,7 +14,7 @@
 
 #include <linux/ioctl.h>
 #include <linux/virtio_config.h>
-#include <linux/virtio_ring.h>
+#include "hw/virtio/virtio_ring.h"
 
 struct vhost_vring_state {
 	unsigned int index;
-- 
1.9.3

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

* [Qemu-devel] [PULL 05/26] block: Always compile virtio-blk dataplane
  2014-09-05 16:13 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (3 preceding siblings ...)
  2014-09-05 16:13 ` [Qemu-devel] [PULL 04/26] virtio: Import virtio_vring.h Stefan Hajnoczi
@ 2014-09-05 16:13 ` Stefan Hajnoczi
  2014-09-05 16:13 ` [Qemu-devel] [PULL 06/26] tests: Functions bus_foreach and device_find from libqos virtio API Stefan Hajnoczi
                   ` (21 subsequent siblings)
  26 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2014-09-05 16:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Fam Zheng, Stefan Hajnoczi

From: Fam Zheng <famz@redhat.com>

Dataplane doesn't depend on linux-aio any more, so we don't need the
compiling condition now.

Configure options are kept but just print a message.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 configure                      | 21 ++-------------------
 hw/block/Makefile.objs         |  2 +-
 hw/block/virtio-blk.c          | 20 ++------------------
 hw/virtio/Makefile.objs        |  2 +-
 include/hw/virtio/virtio-blk.h |  2 --
 5 files changed, 6 insertions(+), 41 deletions(-)

diff --git a/configure b/configure
index 961bf6f..c539786 100755
--- a/configure
+++ b/configure
@@ -327,7 +327,6 @@ glusterfs=""
 glusterfs_discard="no"
 glusterfs_zerofill="no"
 archipelago=""
-virtio_blk_data_plane=""
 gtk=""
 gtkabi=""
 vte=""
@@ -1092,9 +1091,8 @@ for opt do
   ;;
   --enable-archipelago) archipelago="yes"
   ;;
-  --disable-virtio-blk-data-plane) virtio_blk_data_plane="no"
-  ;;
-  --enable-virtio-blk-data-plane) virtio_blk_data_plane="yes"
+  --disable-virtio-blk-data-plane|--enable-virtio-blk-data-plane)
+      echo "$0: $opt is obsolete, virtio-blk data-plane is always on" >&2
   ;;
   --disable-gtk) gtk="no"
   ;;
@@ -2936,16 +2934,6 @@ else
 fi
 
 ##########################################
-# adjust virtio-blk-data-plane based on linux-aio
-
-if test "$virtio_blk_data_plane" = "yes" -a \
-	"$linux_aio" != "yes" ; then
-  error_exit "virtio-blk-data-plane requires Linux AIO, please try --enable-linux-aio"
-elif test -z "$virtio_blk_data_plane" ; then
-  virtio_blk_data_plane=$linux_aio
-fi
-
-##########################################
 # attr probe
 
 if test "$attr" != "no" ; then
@@ -4319,7 +4307,6 @@ echo "coroutine backend $coroutine"
 echo "coroutine pool    $coroutine_pool"
 echo "GlusterFS support $glusterfs"
 echo "Archipelago support $archipelago"
-echo "virtio-blk-data-plane $virtio_blk_data_plane"
 echo "gcov              $gcov_tool"
 echo "gcov enabled      $gcov"
 echo "TPM support       $tpm"
@@ -4778,10 +4765,6 @@ if test "$quorum" = "yes" ; then
   echo "CONFIG_QUORUM=y" >> $config_host_mak
 fi
 
-if test "$virtio_blk_data_plane" = "yes" ; then
-  echo 'CONFIG_VIRTIO_BLK_DATA_PLANE=$(CONFIG_VIRTIO)' >> $config_host_mak
-fi
-
 if test "$vhdx" = "yes" ; then
   echo "CONFIG_VHDX=y" >> $config_host_mak
 fi
diff --git a/hw/block/Makefile.objs b/hw/block/Makefile.objs
index bf46f03..d4c3ab7 100644
--- a/hw/block/Makefile.objs
+++ b/hw/block/Makefile.objs
@@ -12,4 +12,4 @@ common-obj-$(CONFIG_NVME_PCI) += nvme.o
 obj-$(CONFIG_SH4) += tc58128.o
 
 obj-$(CONFIG_VIRTIO) += virtio-blk.o
-obj-$(CONFIG_VIRTIO_BLK_DATA_PLANE) += dataplane/
+obj-$(CONFIG_VIRTIO) += dataplane/
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index a7f2827..75b4607 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -18,10 +18,8 @@
 #include "hw/block/block.h"
 #include "sysemu/blockdev.h"
 #include "hw/virtio/virtio-blk.h"
-#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
-# include "dataplane/virtio-blk.h"
-# include "migration/migration.h"
-#endif
+#include "dataplane/virtio-blk.h"
+#include "migration/migration.h"
 #include "block/scsi.h"
 #ifdef __linux__
 # include <scsi/sg.h>
@@ -432,7 +430,6 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
         .num_writes = 0,
     };
 
-#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
     /* Some guests kick before setting VIRTIO_CONFIG_S_DRIVER_OK so start
      * dataplane here instead of waiting for .set_status().
      */
@@ -440,7 +437,6 @@ static void virtio_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq)
         virtio_blk_data_plane_start(s->dataplane);
         return;
     }
-#endif
 
     while ((req = virtio_blk_get_request(s))) {
         virtio_blk_handle_request(req, &mrb);
@@ -497,11 +493,9 @@ static void virtio_blk_reset(VirtIODevice *vdev)
 {
     VirtIOBlock *s = VIRTIO_BLK(vdev);
 
-#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
     if (s->dataplane) {
         virtio_blk_data_plane_stop(s->dataplane);
     }
-#endif
 
     /*
      * This should cancel pending requests, but can't do nicely until there
@@ -591,12 +585,10 @@ static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status)
     VirtIOBlock *s = VIRTIO_BLK(vdev);
     uint32_t features;
 
-#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
     if (s->dataplane && !(status & (VIRTIO_CONFIG_S_DRIVER |
                                     VIRTIO_CONFIG_S_DRIVER_OK))) {
         virtio_blk_data_plane_stop(s->dataplane);
     }
-#endif
 
     if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) {
         return;
@@ -691,7 +683,6 @@ static const BlockDevOps virtio_block_ops = {
     .resize_cb = virtio_blk_resize,
 };
 
-#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
 /* Disable dataplane thread during live migration since it does not
  * update the dirty memory bitmap yet.
  */
@@ -722,7 +713,6 @@ static void virtio_blk_migration_state_changed(Notifier *notifier, void *data)
         }
     }
 }
-#endif /* CONFIG_VIRTIO_BLK_DATA_PLANE */
 
 static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
 {
@@ -759,7 +749,6 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
 
     s->vq = virtio_add_queue(vdev, 128, virtio_blk_handle_output);
     s->complete_request = virtio_blk_complete_request;
-#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
     virtio_blk_data_plane_create(vdev, blk, &s->dataplane, &err);
     if (err != NULL) {
         error_propagate(errp, err);
@@ -768,7 +757,6 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
     }
     s->migration_state_notifier.notify = virtio_blk_migration_state_changed;
     add_migration_state_change_notifier(&s->migration_state_notifier);
-#endif
 
     s->change = qemu_add_vm_change_state_handler(virtio_blk_dma_restart_cb, s);
     register_savevm(dev, "virtio-blk", virtio_blk_id++, 2,
@@ -786,11 +774,9 @@ static void virtio_blk_device_unrealize(DeviceState *dev, Error **errp)
     VirtIODevice *vdev = VIRTIO_DEVICE(dev);
     VirtIOBlock *s = VIRTIO_BLK(dev);
 
-#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
     remove_migration_state_change_notifier(&s->migration_state_notifier);
     virtio_blk_data_plane_destroy(s->dataplane);
     s->dataplane = NULL;
-#endif
     qemu_del_vm_change_state_handler(s->change);
     unregister_savevm(dev, "virtio-blk", s);
     blockdev_mark_auto_del(s->bs);
@@ -815,9 +801,7 @@ static Property virtio_blk_properties[] = {
 #ifdef __linux__
     DEFINE_PROP_BIT("scsi", VirtIOBlock, blk.scsi, 0, true),
 #endif
-#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
     DEFINE_PROP_BIT("x-data-plane", VirtIOBlock, blk.data_plane, 0, false),
-#endif
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
index ec9e855..d21c397 100644
--- a/hw/virtio/Makefile.objs
+++ b/hw/virtio/Makefile.objs
@@ -2,7 +2,7 @@ common-obj-y += virtio-rng.o
 common-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
 common-obj-y += virtio-bus.o
 common-obj-y += virtio-mmio.o
-common-obj-$(CONFIG_VIRTIO_BLK_DATA_PLANE) += dataplane/
+common-obj-$(CONFIG_VIRTIO) += dataplane/
 
 obj-y += virtio.o virtio-balloon.o 
 obj-$(CONFIG_LINUX) += vhost.o vhost-backend.o vhost-user.o
diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h
index afb7b8d..f4c5239 100644
--- a/include/hw/virtio/virtio-blk.h
+++ b/include/hw/virtio/virtio-blk.h
@@ -131,10 +131,8 @@ typedef struct VirtIOBlock {
     VMChangeStateEntry *change;
     /* Function to push to vq and notify guest */
     void (*complete_request)(struct VirtIOBlockReq *req, unsigned char status);
-#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
     Notifier migration_state_notifier;
     struct VirtIOBlockDataPlane *dataplane;
-#endif
 } VirtIOBlock;
 
 typedef struct MultiReqBuffer {
-- 
1.9.3

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

* [Qemu-devel] [PULL 06/26] tests: Functions bus_foreach and device_find from libqos virtio API
  2014-09-05 16:13 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (4 preceding siblings ...)
  2014-09-05 16:13 ` [Qemu-devel] [PULL 05/26] block: Always compile virtio-blk dataplane Stefan Hajnoczi
@ 2014-09-05 16:13 ` Stefan Hajnoczi
  2014-09-05 16:13 ` [Qemu-devel] [PULL 07/26] tests: Add virtio device initialization Stefan Hajnoczi
                   ` (20 subsequent siblings)
  26 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2014-09-05 16:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marc Marí, Peter Maydell, Stefan Hajnoczi

From: Marc Marí <marc.mari.barcelo@gmail.com>

Virtio header has been changed to compile and work with a real device.
Functions bus_foreach and device_find have been implemented for PCI.
Virtio-blk test case now opens a fake device.

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Marc Marí <marc.mari.barcelo@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 tests/Makefile            |  3 +-
 tests/libqos/virtio-pci.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++
 tests/libqos/virtio-pci.h | 24 +++++++++++++++
 tests/libqos/virtio.h     | 23 +++++++++++++++
 tests/virtio-blk-test.c   | 61 +++++++++++++++++++++++++++++++++-----
 5 files changed, 177 insertions(+), 9 deletions(-)
 create mode 100644 tests/libqos/virtio-pci.c
 create mode 100644 tests/libqos/virtio-pci.h
 create mode 100644 tests/libqos/virtio.h

diff --git a/tests/Makefile b/tests/Makefile
index 469c0a5..0572633 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -299,6 +299,7 @@ libqos-obj-y += tests/libqos/i2c.o
 libqos-pc-obj-y = $(libqos-obj-y) tests/libqos/pci-pc.o
 libqos-pc-obj-y += tests/libqos/malloc-pc.o
 libqos-omap-obj-y = $(libqos-obj-y) tests/libqos/i2c-omap.o
+libqos-virtio-obj-y = $(libqos-obj-y) $(libqos-pc-obj-y) tests/libqos/virtio-pci.o
 
 tests/rtc-test$(EXESUF): tests/rtc-test.o
 tests/m48t59-test$(EXESUF): tests/m48t59-test.o
@@ -320,7 +321,7 @@ tests/vmxnet3-test$(EXESUF): tests/vmxnet3-test.o
 tests/ne2000-test$(EXESUF): tests/ne2000-test.o
 tests/wdt_ib700-test$(EXESUF): tests/wdt_ib700-test.o
 tests/virtio-balloon-test$(EXESUF): tests/virtio-balloon-test.o
-tests/virtio-blk-test$(EXESUF): tests/virtio-blk-test.o
+tests/virtio-blk-test$(EXESUF): tests/virtio-blk-test.o $(libqos-virtio-obj-y)
 tests/virtio-net-test$(EXESUF): tests/virtio-net-test.o
 tests/virtio-rng-test$(EXESUF): tests/virtio-rng-test.o
 tests/virtio-scsi-test$(EXESUF): tests/virtio-scsi-test.o
diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c
new file mode 100644
index 0000000..fde1b1f
--- /dev/null
+++ b/tests/libqos/virtio-pci.c
@@ -0,0 +1,75 @@
+/*
+ * libqos virtio PCI driver
+ *
+ * Copyright (c) 2014 Marc Marí
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <glib.h>
+#include "libqtest.h"
+#include "libqos/virtio.h"
+#include "libqos/virtio-pci.h"
+#include "libqos/pci.h"
+#include "libqos/pci-pc.h"
+
+#include "hw/pci/pci_regs.h"
+
+typedef struct QVirtioPCIForeachData {
+    void (*func)(QVirtioDevice *d, void *data);
+    uint16_t device_type;
+    void *user_data;
+} QVirtioPCIForeachData;
+
+static QVirtioPCIDevice *qpcidevice_to_qvirtiodevice(QPCIDevice *pdev)
+{
+    QVirtioPCIDevice *vpcidev;
+    vpcidev = g_malloc0(sizeof(*vpcidev));
+
+    if (pdev) {
+        vpcidev->pdev = pdev;
+        vpcidev->vdev.device_type =
+                            qpci_config_readw(vpcidev->pdev, PCI_SUBSYSTEM_ID);
+    }
+
+    return vpcidev;
+}
+
+static void qvirtio_pci_foreach_callback(
+                        QPCIDevice *dev, int devfn, void *data)
+{
+    QVirtioPCIForeachData *d = data;
+    QVirtioPCIDevice *vpcidev = qpcidevice_to_qvirtiodevice(dev);
+
+    if (vpcidev->vdev.device_type == d->device_type) {
+        d->func(&vpcidev->vdev, d->user_data);
+    } else {
+        g_free(vpcidev);
+    }
+}
+
+static void qvirtio_pci_assign_device(QVirtioDevice *d, void *data)
+{
+    QVirtioPCIDevice **vpcidev = data;
+    *vpcidev = (QVirtioPCIDevice *)d;
+}
+
+void qvirtio_pci_foreach(QPCIBus *bus, uint16_t device_type,
+                void (*func)(QVirtioDevice *d, void *data), void *data)
+{
+    QVirtioPCIForeachData d = { .func = func,
+                                .device_type = device_type,
+                                .user_data = data };
+
+    qpci_device_foreach(bus, QVIRTIO_VENDOR_ID, -1,
+                                qvirtio_pci_foreach_callback, &d);
+}
+
+QVirtioPCIDevice *qvirtio_pci_device_find(QPCIBus *bus, uint16_t device_type)
+{
+    QVirtioPCIDevice *dev = NULL;
+    qvirtio_pci_foreach(bus, device_type, qvirtio_pci_assign_device, &dev);
+
+    return dev;
+}
diff --git a/tests/libqos/virtio-pci.h b/tests/libqos/virtio-pci.h
new file mode 100644
index 0000000..5101abb
--- /dev/null
+++ b/tests/libqos/virtio-pci.h
@@ -0,0 +1,24 @@
+/*
+ * libqos virtio PCI definitions
+ *
+ * Copyright (c) 2014 Marc Marí
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef LIBQOS_VIRTIO_PCI_H
+#define LIBQOS_VIRTIO_PCI_H
+
+#include "libqos/virtio.h"
+#include "libqos/pci.h"
+
+typedef struct QVirtioPCIDevice {
+    QVirtioDevice vdev;
+    QPCIDevice *pdev;
+} QVirtioPCIDevice;
+
+void qvirtio_pci_foreach(QPCIBus *bus, uint16_t device_type,
+                void (*func)(QVirtioDevice *d, void *data), void *data);
+QVirtioPCIDevice *qvirtio_pci_device_find(QPCIBus *bus, uint16_t device_type);
+#endif
diff --git a/tests/libqos/virtio.h b/tests/libqos/virtio.h
new file mode 100644
index 0000000..2a05798
--- /dev/null
+++ b/tests/libqos/virtio.h
@@ -0,0 +1,23 @@
+/*
+ * libqos virtio definitions
+ *
+ * Copyright (c) 2014 Marc Marí
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef LIBQOS_VIRTIO_H
+#define LIBQOS_VIRTIO_H
+
+#define QVIRTIO_VENDOR_ID       0x1AF4
+
+#define QVIRTIO_NET_DEVICE_ID   0x1
+#define QVIRTIO_BLK_DEVICE_ID   0x2
+
+typedef struct QVirtioDevice {
+    /* Device type */
+    uint16_t device_type;
+} QVirtioDevice;
+
+#endif
diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
index d53f875..4d87a3e 100644
--- a/tests/virtio-blk-test.c
+++ b/tests/virtio-blk-test.c
@@ -2,6 +2,7 @@
  * QTest testcase for VirtIO Block Device
  *
  * Copyright (c) 2014 SUSE LINUX Products GmbH
+ * Copyright (c) 2014 Marc Marí
  *
  * This work is licensed under the terms of the GNU GPL, version 2 or later.
  * See the COPYING file in the top-level directory.
@@ -9,12 +10,59 @@
 
 #include <glib.h>
 #include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
 #include "libqtest.h"
-#include "qemu/osdep.h"
+#include "libqos/virtio.h"
+#include "libqos/virtio-pci.h"
+#include "libqos/pci-pc.h"
 
-/* Tests only initialization so far. TODO: Replace with functional tests */
-static void pci_nop(void)
+#define TEST_IMAGE_SIZE (64 * 1024 * 1024)
+#define PCI_SLOT    0x04
+#define PCI_FN      0x00
+
+static QPCIBus *test_start(void)
 {
+    char cmdline[100];
+    char tmp_path[] = "/tmp/qtest.XXXXXX";
+    int fd, ret;
+
+    /* Create a temporary raw image */
+    fd = mkstemp(tmp_path);
+    g_assert_cmpint(fd, >=, 0);
+    ret = ftruncate(fd, TEST_IMAGE_SIZE);
+    g_assert_cmpint(ret, ==, 0);
+    close(fd);
+
+    snprintf(cmdline, 100, "-drive if=none,id=drive0,file=%s "
+                            "-device virtio-blk-pci,drive=drive0,addr=%x.%x",
+                            tmp_path, PCI_SLOT, PCI_FN);
+    qtest_start(cmdline);
+    unlink(tmp_path);
+
+    return qpci_init_pc();
+}
+
+static void test_end(void)
+{
+    qtest_end();
+}
+
+static void pci_basic(void)
+{
+    QVirtioPCIDevice *dev;
+    QPCIBus *bus;
+
+    bus = test_start();
+
+    dev = qvirtio_pci_device_find(bus, QVIRTIO_BLK_DEVICE_ID);
+    g_assert(dev != NULL);
+    g_assert_cmphex(dev->vdev.device_type, ==, QVIRTIO_BLK_DEVICE_ID);
+    g_assert_cmphex(dev->pdev->devfn, ==, ((PCI_SLOT << 3) | PCI_FN));
+
+    g_free(dev);
+    test_end();
 }
 
 int main(int argc, char **argv)
@@ -22,13 +70,10 @@ int main(int argc, char **argv)
     int ret;
 
     g_test_init(&argc, &argv, NULL);
-    qtest_add_func("/virtio/blk/pci/nop", pci_nop);
 
-    qtest_start("-drive id=drv0,if=none,file=/dev/null "
-                "-device virtio-blk-pci,drive=drv0");
-    ret = g_test_run();
+    g_test_add_func("/virtio/blk/pci/basic", pci_basic);
 
-    qtest_end();
+    ret = g_test_run();
 
     return ret;
 }
-- 
1.9.3

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

* [Qemu-devel] [PULL 07/26] tests: Add virtio device initialization
  2014-09-05 16:13 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (5 preceding siblings ...)
  2014-09-05 16:13 ` [Qemu-devel] [PULL 06/26] tests: Functions bus_foreach and device_find from libqos virtio API Stefan Hajnoczi
@ 2014-09-05 16:13 ` Stefan Hajnoczi
  2014-09-05 16:13 ` [Qemu-devel] [PULL 08/26] libqos: Added basic virtqueue support to virtio implementation Stefan Hajnoczi
                   ` (19 subsequent siblings)
  26 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2014-09-05 16:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marc Marí, Peter Maydell, Stefan Hajnoczi

From: Marc Marí <marc.mari.barcelo@gmail.com>

Add functions to read and write virtio header fields.
Add status bit setting in virtio-blk-device.

Signed-off-by: Marc Marí <marc.mari.barcelo@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 tests/Makefile            |  2 +-
 tests/libqos/virtio-pci.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++
 tests/libqos/virtio-pci.h | 18 ++++++++++++
 tests/libqos/virtio.c     | 55 ++++++++++++++++++++++++++++++++++++
 tests/libqos/virtio.h     | 30 ++++++++++++++++++++
 tests/libqtest.c          | 48 ++++++++++++++++++++++++++++++++
 tests/libqtest.h          |  7 +++++
 tests/virtio-blk-test.c   | 31 ++++++++++++++++++---
 8 files changed, 257 insertions(+), 5 deletions(-)
 create mode 100644 tests/libqos/virtio.c

diff --git a/tests/Makefile b/tests/Makefile
index 0572633..d5db97b 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -299,7 +299,7 @@ libqos-obj-y += tests/libqos/i2c.o
 libqos-pc-obj-y = $(libqos-obj-y) tests/libqos/pci-pc.o
 libqos-pc-obj-y += tests/libqos/malloc-pc.o
 libqos-omap-obj-y = $(libqos-obj-y) tests/libqos/i2c-omap.o
-libqos-virtio-obj-y = $(libqos-obj-y) $(libqos-pc-obj-y) tests/libqos/virtio-pci.o
+libqos-virtio-obj-y = $(libqos-obj-y) $(libqos-pc-obj-y) tests/libqos/virtio.o tests/libqos/virtio-pci.o
 
 tests/rtc-test$(EXESUF): tests/rtc-test.o
 tests/m48t59-test$(EXESUF): tests/m48t59-test.o
diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c
index fde1b1f..1a37620 100644
--- a/tests/libqos/virtio-pci.c
+++ b/tests/libqos/virtio-pci.c
@@ -8,6 +8,7 @@
  */
 
 #include <glib.h>
+#include <stdio.h>
 #include "libqtest.h"
 #include "libqos/virtio.h"
 #include "libqos/virtio-pci.h"
@@ -55,6 +56,64 @@ static void qvirtio_pci_assign_device(QVirtioDevice *d, void *data)
     *vpcidev = (QVirtioPCIDevice *)d;
 }
 
+static uint8_t qvirtio_pci_config_readb(QVirtioDevice *d, void *addr)
+{
+    QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
+    return qpci_io_readb(dev->pdev, addr);
+}
+
+static uint16_t qvirtio_pci_config_readw(QVirtioDevice *d, void *addr)
+{
+    QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
+    return qpci_io_readw(dev->pdev, addr);
+}
+
+static uint32_t qvirtio_pci_config_readl(QVirtioDevice *d, void *addr)
+{
+    QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
+    return qpci_io_readl(dev->pdev, addr);
+}
+
+static uint64_t qvirtio_pci_config_readq(QVirtioDevice *d, void *addr)
+{
+    QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
+    int i;
+    uint64_t u64 = 0;
+
+    if (qtest_big_endian()) {
+        for (i = 0; i < 8; ++i) {
+            u64 |= (uint64_t)qpci_io_readb(dev->pdev, addr + i) << (7 - i) * 8;
+        }
+    } else {
+        for (i = 0; i < 8; ++i) {
+            u64 |= (uint64_t)qpci_io_readb(dev->pdev, addr + i) << i * 8;
+        }
+    }
+
+    return u64;
+}
+
+static uint8_t qvirtio_pci_get_status(QVirtioDevice *d)
+{
+    QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
+    return qpci_io_readb(dev->pdev, dev->addr + QVIRTIO_DEVICE_STATUS);
+}
+
+static void qvirtio_pci_set_status(QVirtioDevice *d, uint8_t status)
+{
+    QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
+    qpci_io_writeb(dev->pdev, dev->addr + QVIRTIO_DEVICE_STATUS, status);
+}
+
+const QVirtioBus qvirtio_pci = {
+    .config_readb = qvirtio_pci_config_readb,
+    .config_readw = qvirtio_pci_config_readw,
+    .config_readl = qvirtio_pci_config_readl,
+    .config_readq = qvirtio_pci_config_readq,
+    .get_status = qvirtio_pci_get_status,
+    .set_status = qvirtio_pci_set_status,
+};
+
 void qvirtio_pci_foreach(QPCIBus *bus, uint16_t device_type,
                 void (*func)(QVirtioDevice *d, void *data), void *data)
 {
@@ -73,3 +132,15 @@ QVirtioPCIDevice *qvirtio_pci_device_find(QPCIBus *bus, uint16_t device_type)
 
     return dev;
 }
+
+void qvirtio_pci_device_enable(QVirtioPCIDevice *d)
+{
+    qpci_device_enable(d->pdev);
+    d->addr = qpci_iomap(d->pdev, 0, NULL);
+    g_assert(d->addr != NULL);
+}
+
+void qvirtio_pci_device_disable(QVirtioPCIDevice *d)
+{
+    qpci_iounmap(d->pdev, d->addr);
+}
diff --git a/tests/libqos/virtio-pci.h b/tests/libqos/virtio-pci.h
index 5101abb..26f902e 100644
--- a/tests/libqos/virtio-pci.h
+++ b/tests/libqos/virtio-pci.h
@@ -13,12 +13,30 @@
 #include "libqos/virtio.h"
 #include "libqos/pci.h"
 
+#define QVIRTIO_DEVICE_FEATURES         0x00
+#define QVIRTIO_GUEST_FEATURES          0x04
+#define QVIRTIO_QUEUE_ADDRESS           0x08
+#define QVIRTIO_QUEUE_SIZE              0x0C
+#define QVIRTIO_QUEUE_SELECT            0x0E
+#define QVIRTIO_QUEUE_NOTIFY            0x10
+#define QVIRTIO_DEVICE_STATUS           0x12
+#define QVIRTIO_ISR_STATUS              0x13
+#define QVIRTIO_MSIX_CONF_VECTOR        0x14
+#define QVIRTIO_MSIX_QUEUE_VECTOR       0x16
+#define QVIRTIO_DEVICE_SPECIFIC_MSIX    0x18
+#define QVIRTIO_DEVICE_SPECIFIC_NO_MSIX 0x14
+
 typedef struct QVirtioPCIDevice {
     QVirtioDevice vdev;
     QPCIDevice *pdev;
+    void *addr;
 } QVirtioPCIDevice;
 
+extern const QVirtioBus qvirtio_pci;
+
 void qvirtio_pci_foreach(QPCIBus *bus, uint16_t device_type,
                 void (*func)(QVirtioDevice *d, void *data), void *data);
 QVirtioPCIDevice *qvirtio_pci_device_find(QPCIBus *bus, uint16_t device_type);
+void qvirtio_pci_device_enable(QVirtioPCIDevice *d);
+void qvirtio_pci_device_disable(QVirtioPCIDevice *d);
 #endif
diff --git a/tests/libqos/virtio.c b/tests/libqos/virtio.c
new file mode 100644
index 0000000..577d679
--- /dev/null
+++ b/tests/libqos/virtio.c
@@ -0,0 +1,55 @@
+/*
+ * libqos virtio driver
+ *
+ * Copyright (c) 2014 Marc Marí
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <glib.h>
+#include "libqtest.h"
+#include "libqos/virtio.h"
+
+uint8_t qvirtio_config_readb(const QVirtioBus *bus, QVirtioDevice *d,
+                                                                void *addr)
+{
+    return bus->config_readb(d, addr);
+}
+
+uint16_t qvirtio_config_readw(const QVirtioBus *bus, QVirtioDevice *d,
+                                                                void *addr)
+{
+    return bus->config_readw(d, addr);
+}
+
+uint32_t qvirtio_config_readl(const QVirtioBus *bus, QVirtioDevice *d,
+                                                                void *addr)
+{
+    return bus->config_readl(d, addr);
+}
+
+uint64_t qvirtio_config_readq(const QVirtioBus *bus, QVirtioDevice *d,
+                                                                void *addr)
+{
+    return bus->config_readq(d, addr);
+}
+
+void qvirtio_reset(const QVirtioBus *bus, QVirtioDevice *d)
+{
+    bus->set_status(d, QVIRTIO_RESET);
+    g_assert_cmphex(bus->get_status(d), ==, QVIRTIO_RESET);
+}
+
+void qvirtio_set_acknowledge(const QVirtioBus *bus, QVirtioDevice *d)
+{
+    bus->set_status(d, bus->get_status(d) | QVIRTIO_ACKNOWLEDGE);
+    g_assert_cmphex(bus->get_status(d), ==, QVIRTIO_ACKNOWLEDGE);
+}
+
+void qvirtio_set_driver(const QVirtioBus *bus, QVirtioDevice *d)
+{
+    bus->set_status(d, bus->get_status(d) | QVIRTIO_DRIVER);
+    g_assert_cmphex(bus->get_status(d), ==,
+                                    QVIRTIO_DRIVER | QVIRTIO_ACKNOWLEDGE);
+}
diff --git a/tests/libqos/virtio.h b/tests/libqos/virtio.h
index 2a05798..8d7238b 100644
--- a/tests/libqos/virtio.h
+++ b/tests/libqos/virtio.h
@@ -12,6 +12,10 @@
 
 #define QVIRTIO_VENDOR_ID       0x1AF4
 
+#define QVIRTIO_RESET           0x0
+#define QVIRTIO_ACKNOWLEDGE     0x1
+#define QVIRTIO_DRIVER          0x2
+
 #define QVIRTIO_NET_DEVICE_ID   0x1
 #define QVIRTIO_BLK_DEVICE_ID   0x2
 
@@ -20,4 +24,30 @@ typedef struct QVirtioDevice {
     uint16_t device_type;
 } QVirtioDevice;
 
+typedef struct QVirtioBus {
+    uint8_t (*config_readb)(QVirtioDevice *d, void *addr);
+    uint16_t (*config_readw)(QVirtioDevice *d, void *addr);
+    uint32_t (*config_readl)(QVirtioDevice *d, void *addr);
+    uint64_t (*config_readq)(QVirtioDevice *d, void *addr);
+
+    /* Get status of the device */
+    uint8_t (*get_status)(QVirtioDevice *d);
+
+    /* Set status of the device  */
+    void (*set_status)(QVirtioDevice *d, uint8_t status);
+} QVirtioBus;
+
+uint8_t qvirtio_config_readb(const QVirtioBus *bus, QVirtioDevice *d,
+                                                                void *addr);
+uint16_t qvirtio_config_readw(const QVirtioBus *bus, QVirtioDevice *d,
+                                                                void *addr);
+uint32_t qvirtio_config_readl(const QVirtioBus *bus, QVirtioDevice *d,
+                                                                void *addr);
+uint64_t qvirtio_config_readq(const QVirtioBus *bus, QVirtioDevice *d,
+                                                                void *addr);
+
+void qvirtio_reset(const QVirtioBus *bus, QVirtioDevice *d);
+void qvirtio_set_acknowledge(const QVirtioBus *bus, QVirtioDevice *d);
+void qvirtio_set_driver(const QVirtioBus *bus, QVirtioDevice *d);
+
 #endif
diff --git a/tests/libqtest.c b/tests/libqtest.c
index 5e458e8..9a92aa7 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -696,3 +696,51 @@ void qmp_discard_response(const char *fmt, ...)
     qtest_qmpv_discard_response(global_qtest, fmt, ap);
     va_end(ap);
 }
+
+bool qtest_big_endian(void)
+{
+    const char *arch = qtest_get_arch();
+    int i;
+
+    static const struct {
+        const char *arch;
+        bool big_endian;
+    } endianness[] = {
+        { "aarch64", false },
+        { "alpha", false },
+        { "arm", false },
+        { "cris", false },
+        { "i386", false },
+        { "lm32", true },
+        { "m68k", true },
+        { "microblaze", true },
+        { "microblazeel", false },
+        { "mips", true },
+        { "mips64", true },
+        { "mips64el", false },
+        { "mipsel", false },
+        { "moxie", true },
+        { "or32", true },
+        { "ppc", true },
+        { "ppc64", true },
+        { "ppcemb", true },
+        { "s390x", true },
+        { "sh4", false },
+        { "sh4eb", true },
+        { "sparc", true },
+        { "sparc64", true },
+        { "unicore32", false },
+        { "x86_64", false },
+        { "xtensa", false },
+        { "xtensaeb", true },
+        {},
+    };
+
+    for (i = 0; endianness[i].arch; i++) {
+        if (strcmp(endianness[i].arch, arch) == 0) {
+            return endianness[i].big_endian;
+        }
+    }
+
+    return false;
+}
diff --git a/tests/libqtest.h b/tests/libqtest.h
index 1be0934..3e12cab 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -682,4 +682,11 @@ static inline int64_t clock_set(int64_t val)
     return qtest_clock_set(global_qtest, val);
 }
 
+/**
+ * qtest_big_endian:
+ *
+ * Returns: True if the architecture under test has a big endian configuration.
+ */
+bool qtest_big_endian(void);
+
 #endif
diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
index 4d87a3e..649f7cf 100644
--- a/tests/virtio-blk-test.c
+++ b/tests/virtio-blk-test.c
@@ -49,18 +49,41 @@ static void test_end(void)
     qtest_end();
 }
 
-static void pci_basic(void)
+static QVirtioPCIDevice *virtio_blk_init(QPCIBus *bus)
 {
     QVirtioPCIDevice *dev;
-    QPCIBus *bus;
-
-    bus = test_start();
 
     dev = qvirtio_pci_device_find(bus, QVIRTIO_BLK_DEVICE_ID);
     g_assert(dev != NULL);
     g_assert_cmphex(dev->vdev.device_type, ==, QVIRTIO_BLK_DEVICE_ID);
     g_assert_cmphex(dev->pdev->devfn, ==, ((PCI_SLOT << 3) | PCI_FN));
 
+    qvirtio_pci_device_enable(dev);
+    qvirtio_reset(&qvirtio_pci, &dev->vdev);
+    qvirtio_set_acknowledge(&qvirtio_pci, &dev->vdev);
+    qvirtio_set_driver(&qvirtio_pci, &dev->vdev);
+
+    return dev;
+}
+
+static void pci_basic(void)
+{
+    QVirtioPCIDevice *dev;
+    QPCIBus *bus;
+    void *addr;
+    uint64_t capacity;
+
+    bus = test_start();
+
+    dev = virtio_blk_init(bus);
+
+    /* MSI-X is not enabled */
+    addr = dev->addr + QVIRTIO_DEVICE_SPECIFIC_NO_MSIX;
+
+    capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev, addr);
+    g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
+
+    qvirtio_pci_device_disable(dev);
     g_free(dev);
     test_end();
 }
-- 
1.9.3

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

* [Qemu-devel] [PULL 08/26] libqos: Added basic virtqueue support to virtio implementation
  2014-09-05 16:13 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (6 preceding siblings ...)
  2014-09-05 16:13 ` [Qemu-devel] [PULL 07/26] tests: Add virtio device initialization Stefan Hajnoczi
@ 2014-09-05 16:13 ` Stefan Hajnoczi
  2014-09-05 16:13 ` [Qemu-devel] [PULL 09/26] libqos: Added indirect descriptor " Stefan Hajnoczi
                   ` (18 subsequent siblings)
  26 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2014-09-05 16:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marc Marí, Peter Maydell, Stefan Hajnoczi

From: Marc Marí <marc.mari.barcelo@gmail.com>

Add status changing and feature negotiation.
Add basic virtqueue support for adding and sending virtqueue requests.
Add ISR checking.

[Squashed request endianness fix by Greg Kurz <gkurz@linux.vnet.ibm.com>
--Stefan]

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Marc Marí <marc.mari.barcelo@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 tests/libqos/virtio-pci.c |  82 +++++++++++++++++++
 tests/libqos/virtio-pci.h |   2 +
 tests/libqos/virtio.c     | 100 +++++++++++++++++++++++
 tests/libqos/virtio.h     |  99 +++++++++++++++++++++++
 tests/virtio-blk-test.c   | 196 +++++++++++++++++++++++++++++++++++++++++++++-
 5 files changed, 476 insertions(+), 3 deletions(-)

diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c
index 1a37620..12b06a2 100644
--- a/tests/libqos/virtio-pci.c
+++ b/tests/libqos/virtio-pci.c
@@ -14,6 +14,8 @@
 #include "libqos/virtio-pci.h"
 #include "libqos/pci.h"
 #include "libqos/pci-pc.h"
+#include "libqos/malloc.h"
+#include "libqos/malloc-pc.h"
 
 #include "hw/pci/pci_regs.h"
 
@@ -93,6 +95,18 @@ static uint64_t qvirtio_pci_config_readq(QVirtioDevice *d, void *addr)
     return u64;
 }
 
+static uint32_t qvirtio_pci_get_features(QVirtioDevice *d)
+{
+    QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
+    return qpci_io_readl(dev->pdev, dev->addr + QVIRTIO_DEVICE_FEATURES);
+}
+
+static void qvirtio_pci_set_features(QVirtioDevice *d, uint32_t features)
+{
+    QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
+    qpci_io_writel(dev->pdev, dev->addr + QVIRTIO_GUEST_FEATURES, features);
+}
+
 static uint8_t qvirtio_pci_get_status(QVirtioDevice *d)
 {
     QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
@@ -105,13 +119,81 @@ static void qvirtio_pci_set_status(QVirtioDevice *d, uint8_t status)
     qpci_io_writeb(dev->pdev, dev->addr + QVIRTIO_DEVICE_STATUS, status);
 }
 
+static uint8_t qvirtio_pci_get_isr_status(QVirtioDevice *d)
+{
+    QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
+    return qpci_io_readb(dev->pdev, dev->addr + QVIRTIO_ISR_STATUS);
+}
+
+static void qvirtio_pci_queue_select(QVirtioDevice *d, uint16_t index)
+{
+    QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
+    qpci_io_writeb(dev->pdev, dev->addr + QVIRTIO_QUEUE_SELECT, index);
+}
+
+static uint16_t qvirtio_pci_get_queue_size(QVirtioDevice *d)
+{
+    QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
+    return qpci_io_readw(dev->pdev, dev->addr + QVIRTIO_QUEUE_SIZE);
+}
+
+static void qvirtio_pci_set_queue_address(QVirtioDevice *d, uint32_t pfn)
+{
+    QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
+    qpci_io_writel(dev->pdev, dev->addr + QVIRTIO_QUEUE_ADDRESS, pfn);
+}
+
+static QVirtQueue *qvirtio_pci_virtqueue_setup(QVirtioDevice *d,
+                                        QGuestAllocator *alloc, uint16_t index)
+{
+    uint64_t addr;
+    QVirtQueue *vq;
+
+    vq = g_malloc0(sizeof(*vq));
+
+    qvirtio_pci_queue_select(d, index);
+    vq->index = index;
+    vq->size = qvirtio_pci_get_queue_size(d);
+    vq->free_head = 0;
+    vq->num_free = vq->size;
+    vq->align = QVIRTIO_PCI_ALIGN;
+
+    /* Check different than 0 */
+    g_assert_cmpint(vq->size, !=, 0);
+
+    /* Check power of 2 */
+    g_assert_cmpint(vq->size & (vq->size - 1), ==, 0);
+
+    addr = guest_alloc(alloc, qvring_size(vq->size, QVIRTIO_PCI_ALIGN));
+    qvring_init(alloc, vq, addr);
+    qvirtio_pci_set_queue_address(d, vq->desc / QVIRTIO_PCI_ALIGN);
+
+    /* TODO: MSI-X configuration */
+
+    return vq;
+}
+
+static void qvirtio_pci_virtqueue_kick(QVirtioDevice *d, QVirtQueue *vq)
+{
+    QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
+    qpci_io_writew(dev->pdev, dev->addr + QVIRTIO_QUEUE_NOTIFY, vq->index);
+}
+
 const QVirtioBus qvirtio_pci = {
     .config_readb = qvirtio_pci_config_readb,
     .config_readw = qvirtio_pci_config_readw,
     .config_readl = qvirtio_pci_config_readl,
     .config_readq = qvirtio_pci_config_readq,
+    .get_features = qvirtio_pci_get_features,
+    .set_features = qvirtio_pci_set_features,
     .get_status = qvirtio_pci_get_status,
     .set_status = qvirtio_pci_set_status,
+    .get_isr_status = qvirtio_pci_get_isr_status,
+    .queue_select = qvirtio_pci_queue_select,
+    .get_queue_size = qvirtio_pci_get_queue_size,
+    .set_queue_address = qvirtio_pci_set_queue_address,
+    .virtqueue_setup = qvirtio_pci_virtqueue_setup,
+    .virtqueue_kick = qvirtio_pci_virtqueue_kick,
 };
 
 void qvirtio_pci_foreach(QPCIBus *bus, uint16_t device_type,
diff --git a/tests/libqos/virtio-pci.h b/tests/libqos/virtio-pci.h
index 26f902e..40bd12d 100644
--- a/tests/libqos/virtio-pci.h
+++ b/tests/libqos/virtio-pci.h
@@ -26,6 +26,8 @@
 #define QVIRTIO_DEVICE_SPECIFIC_MSIX    0x18
 #define QVIRTIO_DEVICE_SPECIFIC_NO_MSIX 0x14
 
+#define QVIRTIO_PCI_ALIGN   4096
+
 typedef struct QVirtioPCIDevice {
     QVirtioDevice vdev;
     QPCIDevice *pdev;
diff --git a/tests/libqos/virtio.c b/tests/libqos/virtio.c
index 577d679..de92642 100644
--- a/tests/libqos/virtio.c
+++ b/tests/libqos/virtio.c
@@ -35,6 +35,23 @@ uint64_t qvirtio_config_readq(const QVirtioBus *bus, QVirtioDevice *d,
     return bus->config_readq(d, addr);
 }
 
+uint32_t qvirtio_get_features(const QVirtioBus *bus, QVirtioDevice *d)
+{
+    return bus->get_features(d);
+}
+
+void qvirtio_set_features(const QVirtioBus *bus, QVirtioDevice *d,
+                                                            uint32_t features)
+{
+    bus->set_features(d, features);
+}
+
+QVirtQueue *qvirtqueue_setup(const QVirtioBus *bus, QVirtioDevice *d,
+                                        QGuestAllocator *alloc, uint16_t index)
+{
+    return bus->virtqueue_setup(d, alloc, index);
+}
+
 void qvirtio_reset(const QVirtioBus *bus, QVirtioDevice *d)
 {
     bus->set_status(d, QVIRTIO_RESET);
@@ -53,3 +70,86 @@ void qvirtio_set_driver(const QVirtioBus *bus, QVirtioDevice *d)
     g_assert_cmphex(bus->get_status(d), ==,
                                     QVIRTIO_DRIVER | QVIRTIO_ACKNOWLEDGE);
 }
+
+void qvirtio_set_driver_ok(const QVirtioBus *bus, QVirtioDevice *d)
+{
+    bus->set_status(d, bus->get_status(d) | QVIRTIO_DRIVER_OK);
+    g_assert_cmphex(bus->get_status(d), ==,
+                QVIRTIO_DRIVER_OK | QVIRTIO_DRIVER | QVIRTIO_ACKNOWLEDGE);
+}
+
+bool qvirtio_wait_isr(const QVirtioBus *bus, QVirtioDevice *d, uint8_t mask,
+                                                            uint64_t timeout)
+{
+    do {
+        clock_step(10);
+        if (bus->get_isr_status(d) & mask) {
+            break; /* It has ended */
+        }
+    } while (--timeout);
+
+    return timeout != 0;
+}
+
+void qvring_init(const QGuestAllocator *alloc, QVirtQueue *vq, uint64_t addr)
+{
+    int i;
+
+    vq->desc = addr;
+    vq->avail = vq->desc + vq->size*sizeof(QVRingDesc);
+    vq->used = (uint64_t)((vq->avail + sizeof(uint16_t) * (3 + vq->size)
+        + vq->align - 1) & ~(vq->align - 1));
+
+    for (i = 0; i < vq->size - 1; i++) {
+        /* vq->desc[i].addr */
+        writew(vq->desc + (16 * i), 0);
+        /* vq->desc[i].next */
+        writew(vq->desc + (16 * i) + 14, i + 1);
+    }
+
+    /* vq->avail->flags */
+    writew(vq->avail, 0);
+    /* vq->avail->idx */
+    writew(vq->avail + 2, 0);
+
+    /* vq->used->flags */
+    writew(vq->used, 0);
+}
+
+uint32_t qvirtqueue_add(QVirtQueue *vq, uint64_t data, uint32_t len, bool write,
+                                                                    bool next)
+{
+    uint16_t flags = 0;
+    vq->num_free--;
+
+    if (write) {
+        flags |= QVRING_DESC_F_WRITE;
+    }
+
+    if (next) {
+        flags |= QVRING_DESC_F_NEXT;
+    }
+
+    /* vq->desc[vq->free_head].addr */
+    writeq(vq->desc + (16 * vq->free_head), data);
+    /* vq->desc[vq->free_head].len */
+    writel(vq->desc + (16 * vq->free_head) + 8, len);
+    /* vq->desc[vq->free_head].flags */
+    writew(vq->desc + (16 * vq->free_head) + 12, flags);
+
+    return vq->free_head++; /* Return and increase, in this order */
+}
+
+void qvirtqueue_kick(const QVirtioBus *bus, QVirtioDevice *d, QVirtQueue *vq,
+                                                            uint32_t free_head)
+{
+    /* vq->avail->idx */
+    uint16_t idx = readl(vq->avail + 2);
+
+    /* vq->avail->ring[idx % vq->size] */
+    writel(vq->avail + 4 + (2 * (idx % vq->size)), free_head);
+    /* vq->avail->idx */
+    writel(vq->avail + 2, idx + 1);
+
+    bus->virtqueue_kick(d, vq);
+}
diff --git a/tests/libqos/virtio.h b/tests/libqos/virtio.h
index 8d7238b..aba5a1e 100644
--- a/tests/libqos/virtio.h
+++ b/tests/libqos/virtio.h
@@ -10,33 +10,117 @@
 #ifndef LIBQOS_VIRTIO_H
 #define LIBQOS_VIRTIO_H
 
+#include "libqos/malloc.h"
+
 #define QVIRTIO_VENDOR_ID       0x1AF4
 
 #define QVIRTIO_RESET           0x0
 #define QVIRTIO_ACKNOWLEDGE     0x1
 #define QVIRTIO_DRIVER          0x2
+#define QVIRTIO_DRIVER_OK       0x4
 
 #define QVIRTIO_NET_DEVICE_ID   0x1
 #define QVIRTIO_BLK_DEVICE_ID   0x2
 
+#define QVRING_DESC_F_NEXT      0x1
+#define QVRING_DESC_F_WRITE     0x2
+#define QVRING_DESC_F_INDIRECT  0x4
+
+#define QVIRTIO_F_NOTIFY_ON_EMPTY       0x01000000
+#define QVIRTIO_F_ANY_LAYOUT            0x08000000
+#define QVIRTIO_F_RING_INDIRECT_DESC    0x10000000
+#define QVIRTIO_F_RING_EVENT_IDX        0x20000000
+#define QVIRTIO_F_BAD_FEATURE           0x40000000
+
+#define QVRING_AVAIL_F_NO_INTERRUPT     1
+
+#define QVRING_USED_F_NO_NOTIFY     1
+
 typedef struct QVirtioDevice {
     /* Device type */
     uint16_t device_type;
 } QVirtioDevice;
 
+typedef struct QVRingDesc {
+    uint64_t addr;
+    uint32_t len;
+    uint16_t flags;
+    uint16_t next;
+} QVRingDesc;
+
+typedef struct QVRingAvail {
+    uint16_t flags;
+    uint16_t idx;
+    uint16_t ring[0]; /* This is an array of uint16_t */
+} QVRingAvail;
+
+typedef struct QVRingUsedElem {
+    uint32_t id;
+    uint32_t len;
+} QVRingUsedElem;
+
+typedef struct QVRingUsed {
+    uint16_t flags;
+    uint16_t idx;
+    QVRingUsedElem ring[0]; /* This is an array of QVRingUsedElem structs */
+} QVRingUsed;
+
+typedef struct QVirtQueue {
+    uint64_t desc; /* This points to an array of QVRingDesc */
+    uint64_t avail; /* This points to a QVRingAvail */
+    uint64_t used; /* This points to a QVRingDesc */
+    uint16_t index;
+    uint32_t size;
+    uint32_t free_head;
+    uint32_t num_free;
+    uint32_t align;
+} QVirtQueue;
+
 typedef struct QVirtioBus {
     uint8_t (*config_readb)(QVirtioDevice *d, void *addr);
     uint16_t (*config_readw)(QVirtioDevice *d, void *addr);
     uint32_t (*config_readl)(QVirtioDevice *d, void *addr);
     uint64_t (*config_readq)(QVirtioDevice *d, void *addr);
 
+    /* Get features of the device */
+    uint32_t (*get_features)(QVirtioDevice *d);
+
+    /* Get features of the device */
+    void (*set_features)(QVirtioDevice *d, uint32_t features);
+
     /* Get status of the device */
     uint8_t (*get_status)(QVirtioDevice *d);
 
     /* Set status of the device  */
     void (*set_status)(QVirtioDevice *d, uint8_t status);
+
+    /* Get the ISR status of the device */
+    uint8_t (*get_isr_status)(QVirtioDevice *d);
+
+    /* Select a queue to work on */
+    void (*queue_select)(QVirtioDevice *d, uint16_t index);
+
+    /* Get the size of the selected queue */
+    uint16_t (*get_queue_size)(QVirtioDevice *d);
+
+    /* Set the address of the selected queue */
+    void (*set_queue_address)(QVirtioDevice *d, uint32_t pfn);
+
+    /* Setup the virtqueue specified by index */
+    QVirtQueue *(*virtqueue_setup)(QVirtioDevice *d, QGuestAllocator *alloc,
+                                                                uint16_t index);
+
+    /* Notify changes in virtqueue */
+    void (*virtqueue_kick)(QVirtioDevice *d, QVirtQueue *vq);
 } QVirtioBus;
 
+static inline uint32_t qvring_size(uint32_t num, uint32_t align)
+{
+    return ((sizeof(struct QVRingDesc) * num + sizeof(uint16_t) * (3 + num)
+        + align - 1) & ~(align - 1))
+        + sizeof(uint16_t) * 3 + sizeof(struct QVRingUsedElem) * num;
+}
+
 uint8_t qvirtio_config_readb(const QVirtioBus *bus, QVirtioDevice *d,
                                                                 void *addr);
 uint16_t qvirtio_config_readw(const QVirtioBus *bus, QVirtioDevice *d,
@@ -45,9 +129,24 @@ uint32_t qvirtio_config_readl(const QVirtioBus *bus, QVirtioDevice *d,
                                                                 void *addr);
 uint64_t qvirtio_config_readq(const QVirtioBus *bus, QVirtioDevice *d,
                                                                 void *addr);
+uint32_t qvirtio_get_features(const QVirtioBus *bus, QVirtioDevice *d);
+void qvirtio_set_features(const QVirtioBus *bus, QVirtioDevice *d,
+                                                            uint32_t features);
 
 void qvirtio_reset(const QVirtioBus *bus, QVirtioDevice *d);
 void qvirtio_set_acknowledge(const QVirtioBus *bus, QVirtioDevice *d);
 void qvirtio_set_driver(const QVirtioBus *bus, QVirtioDevice *d);
+void qvirtio_set_driver_ok(const QVirtioBus *bus, QVirtioDevice *d);
+
+bool qvirtio_wait_isr(const QVirtioBus *bus, QVirtioDevice *d, uint8_t mask,
+                                                            uint64_t timeout);
+QVirtQueue *qvirtqueue_setup(const QVirtioBus *bus, QVirtioDevice *d,
+                                        QGuestAllocator *alloc, uint16_t index);
+
+void qvring_init(const QGuestAllocator *alloc, QVirtQueue *vq, uint64_t addr);
+uint32_t qvirtqueue_add(QVirtQueue *vq, uint64_t data, uint32_t len, bool write,
+                                                                    bool next);
+void qvirtqueue_kick(const QVirtioBus *bus, QVirtioDevice *d, QVirtQueue *vq,
+                                                            uint32_t free_head);
 
 #endif
diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
index 649f7cf..b048938 100644
--- a/tests/virtio-blk-test.c
+++ b/tests/virtio-blk-test.c
@@ -17,10 +17,41 @@
 #include "libqos/virtio.h"
 #include "libqos/virtio-pci.h"
 #include "libqos/pci-pc.h"
+#include "libqos/malloc.h"
+#include "libqos/malloc-pc.h"
+#include "qemu/bswap.h"
 
-#define TEST_IMAGE_SIZE (64 * 1024 * 1024)
-#define PCI_SLOT    0x04
-#define PCI_FN      0x00
+#define QVIRTIO_BLK_F_BARRIER       0x00000001
+#define QVIRTIO_BLK_F_SIZE_MAX      0x00000002
+#define QVIRTIO_BLK_F_SEG_MAX       0x00000004
+#define QVIRTIO_BLK_F_GEOMETRY      0x00000010
+#define QVIRTIO_BLK_F_RO            0x00000020
+#define QVIRTIO_BLK_F_BLK_SIZE      0x00000040
+#define QVIRTIO_BLK_F_SCSI          0x00000080
+#define QVIRTIO_BLK_F_WCE           0x00000200
+#define QVIRTIO_BLK_F_TOPOLOGY      0x00000400
+#define QVIRTIO_BLK_F_CONFIG_WCE    0x00000800
+
+#define QVIRTIO_BLK_T_IN            0
+#define QVIRTIO_BLK_T_OUT           1
+#define QVIRTIO_BLK_T_SCSI_CMD      2
+#define QVIRTIO_BLK_T_SCSI_CMD_OUT  3
+#define QVIRTIO_BLK_T_FLUSH         4
+#define QVIRTIO_BLK_T_FLUSH_OUT     5
+#define QVIRTIO_BLK_T_GET_ID        8
+
+#define TEST_IMAGE_SIZE         (64 * 1024 * 1024)
+#define QVIRTIO_BLK_TIMEOUT     100
+#define PCI_SLOT                0x04
+#define PCI_FN                  0x00
+
+typedef struct QVirtioBlkReq {
+    uint32_t type;
+    uint32_t ioprio;
+    uint64_t sector;
+    char *data;
+    uint8_t status;
+} QVirtioBlkReq;
 
 static QPCIBus *test_start(void)
 {
@@ -66,12 +97,53 @@ static QVirtioPCIDevice *virtio_blk_init(QPCIBus *bus)
     return dev;
 }
 
+static inline void virtio_blk_fix_request(QVirtioBlkReq *req)
+{
+#ifdef HOST_WORDS_BIGENDIAN
+    bool host_endian = true;
+#else
+    bool host_endian = false;
+#endif
+
+    if (qtest_big_endian() != host_endian) {
+        req->type = bswap32(req->type);
+        req->ioprio = bswap32(req->ioprio);
+        req->sector = bswap64(req->sector);
+    }
+}
+
+static uint64_t virtio_blk_request(QGuestAllocator *alloc, QVirtioBlkReq *req,
+                                                            uint64_t data_size)
+{
+    uint64_t addr;
+    uint8_t status = 0xFF;
+
+    g_assert_cmpuint(data_size % 512, ==, 0);
+    addr = guest_alloc(alloc, sizeof(*req) + data_size);
+
+    virtio_blk_fix_request(req);
+
+    memwrite(addr, req, 16);
+    memwrite(addr + 16, req->data, data_size);
+    memwrite(addr + 16 + data_size, &status, sizeof(status));
+
+    return addr;
+}
+
 static void pci_basic(void)
 {
     QVirtioPCIDevice *dev;
     QPCIBus *bus;
+    QVirtQueue *vq;
+    QGuestAllocator *alloc;
+    QVirtioBlkReq req;
     void *addr;
+    uint64_t req_addr;
     uint64_t capacity;
+    uint32_t features;
+    uint32_t free_head;
+    uint8_t status;
+    char *data;
 
     bus = test_start();
 
@@ -83,6 +155,124 @@ static void pci_basic(void)
     capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev, addr);
     g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
 
+    features = qvirtio_get_features(&qvirtio_pci, &dev->vdev);
+    features = features & ~(QVIRTIO_F_BAD_FEATURE |
+                    QVIRTIO_F_RING_INDIRECT_DESC | QVIRTIO_F_RING_EVENT_IDX |
+                            QVIRTIO_BLK_F_SCSI);
+    qvirtio_set_features(&qvirtio_pci, &dev->vdev, features);
+
+    alloc = pc_alloc_init();
+    vq = qvirtqueue_setup(&qvirtio_pci, &dev->vdev, alloc, 0);
+
+    qvirtio_set_driver_ok(&qvirtio_pci, &dev->vdev);
+
+    /* Write and read with 2 descriptor layout */
+    /* Write request */
+    req.type = QVIRTIO_BLK_T_OUT;
+    req.ioprio = 1;
+    req.sector = 0;
+    req.data = g_malloc0(512);
+    strcpy(req.data, "TEST");
+
+    req_addr = virtio_blk_request(alloc, &req, 512);
+
+    g_free(req.data);
+
+    free_head = qvirtqueue_add(vq, req_addr, 528, false, true);
+    qvirtqueue_add(vq, req_addr + 528, 1, true, false);
+    qvirtqueue_kick(&qvirtio_pci, &dev->vdev, vq, free_head);
+
+    g_assert(qvirtio_wait_isr(&qvirtio_pci, &dev->vdev, 0x1,
+                                                        QVIRTIO_BLK_TIMEOUT));
+    status = readb(req_addr + 528);
+    g_assert_cmpint(status, ==, 0);
+
+    guest_free(alloc, req_addr);
+
+    /* Read request */
+    req.type = QVIRTIO_BLK_T_IN;
+    req.ioprio = 1;
+    req.sector = 0;
+    req.data = g_malloc0(512);
+
+    req_addr = virtio_blk_request(alloc, &req, 512);
+
+    g_free(req.data);
+
+    free_head = qvirtqueue_add(vq, req_addr, 16, false, true);
+    qvirtqueue_add(vq, req_addr + 16, 513, true, false);
+
+    qvirtqueue_kick(&qvirtio_pci, &dev->vdev, vq, free_head);
+
+    g_assert(qvirtio_wait_isr(&qvirtio_pci, &dev->vdev, 0x1,
+                                                        QVIRTIO_BLK_TIMEOUT));
+    status = readb(req_addr + 528);
+    g_assert_cmpint(status, ==, 0);
+
+    data = g_malloc0(512);
+    memread(req_addr + 16, data, 512);
+    g_assert_cmpstr(data, ==, "TEST");
+    g_free(data);
+
+    guest_free(alloc, req_addr);
+
+    /* Write and read with 3 descriptor layout */
+    /* Write request */
+    req.type = QVIRTIO_BLK_T_OUT;
+    req.ioprio = 1;
+    req.sector = 1;
+    req.data = g_malloc0(512);
+    strcpy(req.data, "TEST");
+
+    req_addr = virtio_blk_request(alloc, &req, 512);
+
+    g_free(req.data);
+
+    free_head = qvirtqueue_add(vq, req_addr, 16, false, true);
+    qvirtqueue_add(vq, req_addr + 16, 512, false, true);
+    qvirtqueue_add(vq, req_addr + 528, 1, true, false);
+
+    qvirtqueue_kick(&qvirtio_pci, &dev->vdev, vq, free_head);
+
+    g_assert(qvirtio_wait_isr(&qvirtio_pci, &dev->vdev, 0x1,
+                                                        QVIRTIO_BLK_TIMEOUT));
+    status = readb(req_addr + 528);
+    g_assert_cmpint(status, ==, 0);
+
+    guest_free(alloc, req_addr);
+
+    /* Read request */
+    req.type = QVIRTIO_BLK_T_IN;
+    req.ioprio = 1;
+    req.sector = 1;
+    req.data = g_malloc0(512);
+
+    req_addr = virtio_blk_request(alloc, &req, 512);
+
+    g_free(req.data);
+
+    free_head = qvirtqueue_add(vq, req_addr, 16, false, true);
+    qvirtqueue_add(vq, req_addr + 16, 512, true, true);
+    qvirtqueue_add(vq, req_addr + 528, 1, true, false);
+
+    qvirtqueue_kick(&qvirtio_pci, &dev->vdev, vq, free_head);
+
+    g_assert(qvirtio_wait_isr(&qvirtio_pci, &dev->vdev, 0x1,
+                                                        QVIRTIO_BLK_TIMEOUT));
+    status = readb(req_addr + 528);
+    g_assert_cmpint(status, ==, 0);
+
+    guest_free(alloc, req_addr);
+
+    data = g_malloc0(512);
+    memread(req_addr + 16, data, 512);
+    g_assert_cmpstr(data, ==, "TEST");
+    g_free(data);
+
+    guest_free(alloc, req_addr);
+
+    /* End test */
+    guest_free(alloc, vq->desc);
     qvirtio_pci_device_disable(dev);
     g_free(dev);
     test_end();
-- 
1.9.3

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

* [Qemu-devel] [PULL 09/26] libqos: Added indirect descriptor support to virtio implementation
  2014-09-05 16:13 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (7 preceding siblings ...)
  2014-09-05 16:13 ` [Qemu-devel] [PULL 08/26] libqos: Added basic virtqueue support to virtio implementation Stefan Hajnoczi
@ 2014-09-05 16:13 ` Stefan Hajnoczi
  2014-09-05 16:13 ` [Qemu-devel] [PULL 10/26] libqos: Added test case for configuration changes in virtio-blk test Stefan Hajnoczi
                   ` (17 subsequent siblings)
  26 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2014-09-05 16:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marc Marí, Peter Maydell, Stefan Hajnoczi

From: Marc Marí <marc.mari.barcelo@gmail.com>

Add functions necessary for working with indirect descriptors.
Add test using new functions.

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Marc Marí <marc.mari.barcelo@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 tests/libqos/virtio-pci.c |  10 +++++
 tests/libqos/virtio.c     |  64 +++++++++++++++++++++++++++++
 tests/libqos/virtio.h     |  22 +++++++++-
 tests/virtio-blk-test.c   | 100 ++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 195 insertions(+), 1 deletion(-)

diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c
index 12b06a2..cf15f7a 100644
--- a/tests/libqos/virtio-pci.c
+++ b/tests/libqos/virtio-pci.c
@@ -107,6 +107,12 @@ static void qvirtio_pci_set_features(QVirtioDevice *d, uint32_t features)
     qpci_io_writel(dev->pdev, dev->addr + QVIRTIO_GUEST_FEATURES, features);
 }
 
+static uint32_t qvirtio_pci_get_guest_features(QVirtioDevice *d)
+{
+    QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
+    return qpci_io_readl(dev->pdev, dev->addr + QVIRTIO_GUEST_FEATURES);
+}
+
 static uint8_t qvirtio_pci_get_status(QVirtioDevice *d)
 {
     QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
@@ -146,10 +152,12 @@ static void qvirtio_pci_set_queue_address(QVirtioDevice *d, uint32_t pfn)
 static QVirtQueue *qvirtio_pci_virtqueue_setup(QVirtioDevice *d,
                                         QGuestAllocator *alloc, uint16_t index)
 {
+    uint32_t feat;
     uint64_t addr;
     QVirtQueue *vq;
 
     vq = g_malloc0(sizeof(*vq));
+    feat = qvirtio_pci_get_guest_features(d);
 
     qvirtio_pci_queue_select(d, index);
     vq->index = index;
@@ -157,6 +165,7 @@ static QVirtQueue *qvirtio_pci_virtqueue_setup(QVirtioDevice *d,
     vq->free_head = 0;
     vq->num_free = vq->size;
     vq->align = QVIRTIO_PCI_ALIGN;
+    vq->indirect = (feat & QVIRTIO_F_RING_INDIRECT_DESC) != 0;
 
     /* Check different than 0 */
     g_assert_cmpint(vq->size, !=, 0);
@@ -186,6 +195,7 @@ const QVirtioBus qvirtio_pci = {
     .config_readq = qvirtio_pci_config_readq,
     .get_features = qvirtio_pci_get_features,
     .set_features = qvirtio_pci_set_features,
+    .get_guest_features = qvirtio_pci_get_guest_features,
     .get_status = qvirtio_pci_get_status,
     .set_status = qvirtio_pci_set_status,
     .get_isr_status = qvirtio_pci_get_isr_status,
diff --git a/tests/libqos/virtio.c b/tests/libqos/virtio.c
index de92642..b1cab1f 100644
--- a/tests/libqos/virtio.c
+++ b/tests/libqos/virtio.c
@@ -116,6 +116,51 @@ void qvring_init(const QGuestAllocator *alloc, QVirtQueue *vq, uint64_t addr)
     writew(vq->used, 0);
 }
 
+QVRingIndirectDesc *qvring_indirect_desc_setup(QVirtioDevice *d,
+                                        QGuestAllocator *alloc, uint16_t elem)
+{
+    int i;
+    QVRingIndirectDesc *indirect = g_malloc(sizeof(*indirect));
+
+    indirect->index = 0;
+    indirect->elem = elem;
+    indirect->desc = guest_alloc(alloc, sizeof(QVRingDesc)*elem);
+
+    for (i = 0; i < elem - 1; ++i) {
+        /* indirect->desc[i].addr */
+        writeq(indirect->desc + (16 * i), 0);
+        /* indirect->desc[i].flags */
+        writew(indirect->desc + (16 * i) + 12, QVRING_DESC_F_NEXT);
+        /* indirect->desc[i].next */
+        writew(indirect->desc + (16 * i) + 14, i + 1);
+    }
+
+    return indirect;
+}
+
+void qvring_indirect_desc_add(QVRingIndirectDesc *indirect, uint64_t data,
+                                                    uint32_t len, bool write)
+{
+    uint16_t flags;
+
+    g_assert_cmpint(indirect->index, <, indirect->elem);
+
+    flags = readw(indirect->desc + (16 * indirect->index) + 12);
+
+    if (write) {
+        flags |= QVRING_DESC_F_WRITE;
+    }
+
+    /* indirect->desc[indirect->index].addr */
+    writeq(indirect->desc + (16 * indirect->index), data);
+    /* indirect->desc[indirect->index].len */
+    writel(indirect->desc + (16 * indirect->index) + 8, len);
+    /* indirect->desc[indirect->index].flags */
+    writew(indirect->desc + (16 * indirect->index) + 12, flags);
+
+    indirect->index++;
+}
+
 uint32_t qvirtqueue_add(QVirtQueue *vq, uint64_t data, uint32_t len, bool write,
                                                                     bool next)
 {
@@ -140,6 +185,25 @@ uint32_t qvirtqueue_add(QVirtQueue *vq, uint64_t data, uint32_t len, bool write,
     return vq->free_head++; /* Return and increase, in this order */
 }
 
+uint32_t qvirtqueue_add_indirect(QVirtQueue *vq, QVRingIndirectDesc *indirect)
+{
+    g_assert(vq->indirect);
+    g_assert_cmpint(vq->size, >=, indirect->elem);
+    g_assert_cmpint(indirect->index, ==, indirect->elem);
+
+    vq->num_free--;
+
+    /* vq->desc[vq->free_head].addr */
+    writeq(vq->desc + (16 * vq->free_head), indirect->desc);
+    /* vq->desc[vq->free_head].len */
+    writel(vq->desc + (16 * vq->free_head) + 8,
+                                        sizeof(QVRingDesc) * indirect->elem);
+    /* vq->desc[vq->free_head].flags */
+    writew(vq->desc + (16 * vq->free_head) + 12, QVRING_DESC_F_INDIRECT);
+
+    return vq->free_head++; /* Return and increase, in this order */
+}
+
 void qvirtqueue_kick(const QVirtioBus *bus, QVirtioDevice *d, QVirtQueue *vq,
                                                             uint32_t free_head)
 {
diff --git a/tests/libqos/virtio.h b/tests/libqos/virtio.h
index aba5a1e..1860660 100644
--- a/tests/libqos/virtio.h
+++ b/tests/libqos/virtio.h
@@ -22,6 +22,11 @@
 #define QVIRTIO_NET_DEVICE_ID   0x1
 #define QVIRTIO_BLK_DEVICE_ID   0x2
 
+#define QVIRTIO_F_NOTIFY_ON_EMPTY       0x01000000
+#define QVIRTIO_F_ANY_LAYOUT            0x08000000
+#define QVIRTIO_F_RING_INDIRECT_DESC    0x10000000
+#define QVIRTIO_F_RING_EVENT_IDX        0x20000000
+
 #define QVRING_DESC_F_NEXT      0x1
 #define QVRING_DESC_F_WRITE     0x2
 #define QVRING_DESC_F_INDIRECT  0x4
@@ -74,8 +79,15 @@ typedef struct QVirtQueue {
     uint32_t free_head;
     uint32_t num_free;
     uint32_t align;
+    bool indirect;
 } QVirtQueue;
 
+typedef struct QVRingIndirectDesc {
+    uint64_t desc; /* This points to an array fo QVRingDesc */
+    uint16_t index;
+    uint16_t elem;
+} QVRingIndirectDesc;
+
 typedef struct QVirtioBus {
     uint8_t (*config_readb)(QVirtioDevice *d, void *addr);
     uint16_t (*config_readw)(QVirtioDevice *d, void *addr);
@@ -85,9 +97,12 @@ typedef struct QVirtioBus {
     /* Get features of the device */
     uint32_t (*get_features)(QVirtioDevice *d);
 
-    /* Get features of the device */
+    /* Set features of the device */
     void (*set_features)(QVirtioDevice *d, uint32_t features);
 
+    /* Get features of the guest */
+    uint32_t (*get_guest_features)(QVirtioDevice *d);
+
     /* Get status of the device */
     uint8_t (*get_status)(QVirtioDevice *d);
 
@@ -144,8 +159,13 @@ QVirtQueue *qvirtqueue_setup(const QVirtioBus *bus, QVirtioDevice *d,
                                         QGuestAllocator *alloc, uint16_t index);
 
 void qvring_init(const QGuestAllocator *alloc, QVirtQueue *vq, uint64_t addr);
+QVRingIndirectDesc *qvring_indirect_desc_setup(QVirtioDevice *d,
+                                        QGuestAllocator *alloc, uint16_t elem);
+void qvring_indirect_desc_add(QVRingIndirectDesc *indirect, uint64_t data,
+                                                    uint32_t len, bool write);
 uint32_t qvirtqueue_add(QVirtQueue *vq, uint64_t data, uint32_t len, bool write,
                                                                     bool next);
+uint32_t qvirtqueue_add_indirect(QVirtQueue *vq, QVRingIndirectDesc *indirect);
 void qvirtqueue_kick(const QVirtioBus *bus, QVirtioDevice *d, QVirtQueue *vq,
                                                             uint32_t free_head);
 
diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
index b048938..2f9cc2b 100644
--- a/tests/virtio-blk-test.c
+++ b/tests/virtio-blk-test.c
@@ -278,6 +278,105 @@ static void pci_basic(void)
     test_end();
 }
 
+static void pci_indirect(void)
+{
+    QVirtioPCIDevice *dev;
+    QPCIBus *bus;
+    QVirtQueue *vq;
+    QGuestAllocator *alloc;
+    QVirtioBlkReq req;
+    QVRingIndirectDesc *indirect;
+    void *addr;
+    uint64_t req_addr;
+    uint64_t capacity;
+    uint32_t features;
+    uint32_t free_head;
+    uint8_t status;
+    char *data;
+
+    bus = test_start();
+
+    dev = virtio_blk_init(bus);
+
+    /* MSI-X is not enabled */
+    addr = dev->addr + QVIRTIO_DEVICE_SPECIFIC_NO_MSIX;
+
+    capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev, addr);
+    g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
+
+    features = qvirtio_get_features(&qvirtio_pci, &dev->vdev);
+    g_assert_cmphex(features & QVIRTIO_F_RING_INDIRECT_DESC, !=, 0);
+    features = features & ~(QVIRTIO_F_BAD_FEATURE | QVIRTIO_F_RING_EVENT_IDX |
+                                                            QVIRTIO_BLK_F_SCSI);
+    qvirtio_set_features(&qvirtio_pci, &dev->vdev, features);
+
+    alloc = pc_alloc_init();
+    vq = qvirtqueue_setup(&qvirtio_pci, &dev->vdev, alloc, 0);
+
+    qvirtio_set_driver_ok(&qvirtio_pci, &dev->vdev);
+
+    /* Write request */
+    req.type = QVIRTIO_BLK_T_OUT;
+    req.ioprio = 1;
+    req.sector = 0;
+    req.data = g_malloc0(512);
+    strcpy(req.data, "TEST");
+
+    req_addr = virtio_blk_request(alloc, &req, 512);
+
+    g_free(req.data);
+
+    indirect = qvring_indirect_desc_setup(&dev->vdev, alloc, 2);
+    qvring_indirect_desc_add(indirect, req_addr, 528, false);
+    qvring_indirect_desc_add(indirect, req_addr + 528, 1, true);
+    free_head = qvirtqueue_add_indirect(vq, indirect);
+    qvirtqueue_kick(&qvirtio_pci, &dev->vdev, vq, free_head);
+
+    g_assert(qvirtio_wait_isr(&qvirtio_pci, &dev->vdev, 0x1,
+                                                        QVIRTIO_BLK_TIMEOUT));
+    status = readb(req_addr + 528);
+    g_assert_cmpint(status, ==, 0);
+
+    g_free(indirect);
+    guest_free(alloc, req_addr);
+
+    /* Read request */
+    req.type = QVIRTIO_BLK_T_IN;
+    req.ioprio = 1;
+    req.sector = 0;
+    req.data = g_malloc0(512);
+    strcpy(req.data, "TEST");
+
+    req_addr = virtio_blk_request(alloc, &req, 512);
+
+    g_free(req.data);
+
+    indirect = qvring_indirect_desc_setup(&dev->vdev, alloc, 2);
+    qvring_indirect_desc_add(indirect, req_addr, 16, false);
+    qvring_indirect_desc_add(indirect, req_addr + 16, 513, true);
+    free_head = qvirtqueue_add_indirect(vq, indirect);
+    qvirtqueue_kick(&qvirtio_pci, &dev->vdev, vq, free_head);
+
+    g_assert(qvirtio_wait_isr(&qvirtio_pci, &dev->vdev, 0x1,
+                                                        QVIRTIO_BLK_TIMEOUT));
+    status = readb(req_addr + 528);
+    g_assert_cmpint(status, ==, 0);
+
+    data = g_malloc0(512);
+    memread(req_addr + 16, data, 512);
+    g_assert_cmpstr(data, ==, "TEST");
+    g_free(data);
+
+    g_free(indirect);
+    guest_free(alloc, req_addr);
+
+    /* End test */
+    guest_free(alloc, vq->desc);
+    qvirtio_pci_device_disable(dev);
+    g_free(dev);
+    test_end();
+}
+
 int main(int argc, char **argv)
 {
     int ret;
@@ -285,6 +384,7 @@ int main(int argc, char **argv)
     g_test_init(&argc, &argv, NULL);
 
     g_test_add_func("/virtio/blk/pci/basic", pci_basic);
+    g_test_add_func("/virtio/blk/pci/indirect", pci_indirect);
 
     ret = g_test_run();
 
-- 
1.9.3

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

* [Qemu-devel] [PULL 10/26] libqos: Added test case for configuration changes in virtio-blk test
  2014-09-05 16:13 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (8 preceding siblings ...)
  2014-09-05 16:13 ` [Qemu-devel] [PULL 09/26] libqos: Added indirect descriptor " Stefan Hajnoczi
@ 2014-09-05 16:13 ` Stefan Hajnoczi
  2014-09-05 16:13 ` [Qemu-devel] [PULL 11/26] libqos: Added MSI-X support Stefan Hajnoczi
                   ` (16 subsequent siblings)
  26 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2014-09-05 16:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marc Marí, Peter Maydell, Stefan Hajnoczi

From: Marc Marí <marc.mari.barcelo@gmail.com>

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Marc Marí <marc.mari.barcelo@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 tests/virtio-blk-test.c | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
index 2f9cc2b..672580b 100644
--- a/tests/virtio-blk-test.c
+++ b/tests/virtio-blk-test.c
@@ -377,6 +377,39 @@ static void pci_indirect(void)
     test_end();
 }
 
+static void pci_config(void)
+{
+    QVirtioPCIDevice *dev;
+    QPCIBus *bus;
+    int n_size = TEST_IMAGE_SIZE / 2;
+    void *addr;
+    uint64_t capacity;
+
+    bus = test_start();
+
+    dev = virtio_blk_init(bus);
+
+    /* MSI-X is not enabled */
+    addr = dev->addr + QVIRTIO_DEVICE_SPECIFIC_NO_MSIX;
+
+    capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev, addr);
+    g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
+
+    qvirtio_set_driver_ok(&qvirtio_pci, &dev->vdev);
+
+    qmp("{ 'execute': 'block_resize', 'arguments': { 'device': 'drive0', "
+                                                    " 'size': %d } }", n_size);
+    g_assert(qvirtio_wait_isr(&qvirtio_pci, &dev->vdev, 0x2,
+                                                        QVIRTIO_BLK_TIMEOUT));
+
+    capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev, addr);
+    g_assert_cmpint(capacity, ==, n_size / 512);
+
+    qvirtio_pci_device_disable(dev);
+    g_free(dev);
+    test_end();
+}
+
 int main(int argc, char **argv)
 {
     int ret;
@@ -385,6 +418,7 @@ int main(int argc, char **argv)
 
     g_test_add_func("/virtio/blk/pci/basic", pci_basic);
     g_test_add_func("/virtio/blk/pci/indirect", pci_indirect);
+    g_test_add_func("/virtio/blk/pci/config", pci_config);
 
     ret = g_test_run();
 
-- 
1.9.3

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

* [Qemu-devel] [PULL 11/26] libqos: Added MSI-X support
  2014-09-05 16:13 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (9 preceding siblings ...)
  2014-09-05 16:13 ` [Qemu-devel] [PULL 10/26] libqos: Added test case for configuration changes in virtio-blk test Stefan Hajnoczi
@ 2014-09-05 16:13 ` Stefan Hajnoczi
  2014-09-05 16:13 ` [Qemu-devel] [PULL 12/26] libqos: Added EVENT_IDX support Stefan Hajnoczi
                   ` (15 subsequent siblings)
  26 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2014-09-05 16:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marc Marí, Peter Maydell, Stefan Hajnoczi

From: Marc Marí <marc.mari.barcelo@gmail.com>

Added MSI-X support for qtest PCI.
Added MSI-X support for virtio-pci.
Added MSI-X test case in virtio-blk-test.

Signed-off-by: Marc Marí <marc.mari.barcelo@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 tests/libqos/pci.c        | 111 +++++++++++++++++++++++++++-
 tests/libqos/pci.h        |  10 +++
 tests/libqos/virtio-pci.c | 142 +++++++++++++++++++++++++++++++-----
 tests/libqos/virtio-pci.h |  17 +++++
 tests/libqos/virtio.c     |  17 ++++-
 tests/libqos/virtio.h     |  11 ++-
 tests/virtio-blk-test.c   | 180 ++++++++++++++++++++++++++++++++++++----------
 7 files changed, 426 insertions(+), 62 deletions(-)

diff --git a/tests/libqos/pci.c b/tests/libqos/pci.c
index ce0b308..d5ce683 100644
--- a/tests/libqos/pci.c
+++ b/tests/libqos/pci.c
@@ -15,8 +15,6 @@
 #include "hw/pci/pci_regs.h"
 #include <glib.h>
 
-#include <stdio.h>
-
 void qpci_device_foreach(QPCIBus *bus, int vendor_id, int device_id,
                          void (*func)(QPCIDevice *dev, int devfn, void *data),
                          void *data)
@@ -75,6 +73,115 @@ void qpci_device_enable(QPCIDevice *dev)
     qpci_config_writew(dev, PCI_COMMAND, cmd);
 }
 
+uint8_t qpci_find_capability(QPCIDevice *dev, uint8_t id)
+{
+    uint8_t cap;
+    uint8_t addr = qpci_config_readb(dev, PCI_CAPABILITY_LIST);
+
+    do {
+        cap = qpci_config_readb(dev, addr);
+        if (cap != id) {
+            addr = qpci_config_readb(dev, addr + PCI_CAP_LIST_NEXT);
+        }
+    } while (cap != id && addr != 0);
+
+    return addr;
+}
+
+void qpci_msix_enable(QPCIDevice *dev)
+{
+    uint8_t addr;
+    uint16_t val;
+    uint32_t table;
+    uint8_t bir_table;
+    uint8_t bir_pba;
+    void *offset;
+
+    addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX);
+    g_assert_cmphex(addr, !=, 0);
+
+    val = qpci_config_readw(dev, addr + PCI_MSIX_FLAGS);
+    qpci_config_writew(dev, addr + PCI_MSIX_FLAGS, val | PCI_MSIX_FLAGS_ENABLE);
+
+    table = qpci_config_readl(dev, addr + PCI_MSIX_TABLE);
+    bir_table = table & PCI_MSIX_FLAGS_BIRMASK;
+    offset = qpci_iomap(dev, bir_table, NULL);
+    dev->msix_table = offset + (table & ~PCI_MSIX_FLAGS_BIRMASK);
+
+    table = qpci_config_readl(dev, addr + PCI_MSIX_PBA);
+    bir_pba = table & PCI_MSIX_FLAGS_BIRMASK;
+    if (bir_pba != bir_table) {
+        offset = qpci_iomap(dev, bir_pba, NULL);
+    }
+    dev->msix_pba = offset + (table & ~PCI_MSIX_FLAGS_BIRMASK);
+
+    g_assert(dev->msix_table != NULL);
+    g_assert(dev->msix_pba != NULL);
+    dev->msix_enabled = true;
+}
+
+void qpci_msix_disable(QPCIDevice *dev)
+{
+    uint8_t addr;
+    uint16_t val;
+
+    g_assert(dev->msix_enabled);
+    addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX);
+    g_assert_cmphex(addr, !=, 0);
+    val = qpci_config_readw(dev, addr + PCI_MSIX_FLAGS);
+    qpci_config_writew(dev, addr + PCI_MSIX_FLAGS,
+                                                val & ~PCI_MSIX_FLAGS_ENABLE);
+
+    qpci_iounmap(dev, dev->msix_table);
+    qpci_iounmap(dev, dev->msix_pba);
+    dev->msix_enabled = 0;
+    dev->msix_table = NULL;
+    dev->msix_pba = NULL;
+}
+
+bool qpci_msix_pending(QPCIDevice *dev, uint16_t entry)
+{
+    uint32_t pba_entry;
+    uint8_t bit_n = entry % 32;
+    void *addr = dev->msix_pba + (entry / 32) * PCI_MSIX_ENTRY_SIZE / 4;
+
+    g_assert(dev->msix_enabled);
+    pba_entry = qpci_io_readl(dev, addr);
+    qpci_io_writel(dev, addr, pba_entry & ~(1 << bit_n));
+    return (pba_entry & (1 << bit_n)) != 0;
+}
+
+bool qpci_msix_masked(QPCIDevice *dev, uint16_t entry)
+{
+    uint8_t addr;
+    uint16_t val;
+    void *vector_addr = dev->msix_table + (entry * PCI_MSIX_ENTRY_SIZE);
+
+    g_assert(dev->msix_enabled);
+    addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX);
+    g_assert_cmphex(addr, !=, 0);
+    val = qpci_config_readw(dev, addr + PCI_MSIX_FLAGS);
+
+    if (val & PCI_MSIX_FLAGS_MASKALL) {
+        return true;
+    } else {
+        return (qpci_io_readl(dev, vector_addr + PCI_MSIX_ENTRY_VECTOR_CTRL)
+                                            & PCI_MSIX_ENTRY_CTRL_MASKBIT) != 0;
+    }
+}
+
+uint16_t qpci_msix_table_size(QPCIDevice *dev)
+{
+    uint8_t addr;
+    uint16_t control;
+
+    addr = qpci_find_capability(dev, PCI_CAP_ID_MSIX);
+    g_assert_cmphex(addr, !=, 0);
+
+    control = qpci_config_readw(dev, addr + PCI_MSIX_FLAGS);
+    return (control & PCI_MSIX_FLAGS_QSIZE) + 1;
+}
+
 uint8_t qpci_config_readb(QPCIDevice *dev, uint8_t offset)
 {
     return dev->bus->config_readb(dev->bus, dev->devfn, offset);
diff --git a/tests/libqos/pci.h b/tests/libqos/pci.h
index 9ee048b..d51eb9e 100644
--- a/tests/libqos/pci.h
+++ b/tests/libqos/pci.h
@@ -14,6 +14,7 @@
 #define LIBQOS_PCI_H
 
 #include <stdint.h>
+#include "libqtest.h"
 
 #define QPCI_DEVFN(dev, fn) (((dev) << 3) | (fn))
 
@@ -49,6 +50,9 @@ struct QPCIDevice
 {
     QPCIBus *bus;
     int devfn;
+    bool msix_enabled;
+    void *msix_table;
+    void *msix_pba;
 };
 
 void qpci_device_foreach(QPCIBus *bus, int vendor_id, int device_id,
@@ -57,6 +61,12 @@ void qpci_device_foreach(QPCIBus *bus, int vendor_id, int device_id,
 QPCIDevice *qpci_device_find(QPCIBus *bus, int devfn);
 
 void qpci_device_enable(QPCIDevice *dev);
+uint8_t qpci_find_capability(QPCIDevice *dev, uint8_t id);
+void qpci_msix_enable(QPCIDevice *dev);
+void qpci_msix_disable(QPCIDevice *dev);
+bool qpci_msix_pending(QPCIDevice *dev, uint16_t entry);
+bool qpci_msix_masked(QPCIDevice *dev, uint16_t entry);
+uint16_t qpci_msix_table_size(QPCIDevice *dev);
 
 uint8_t qpci_config_readb(QPCIDevice *dev, uint8_t offset);
 uint16_t qpci_config_readw(QPCIDevice *dev, uint8_t offset);
diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c
index cf15f7a..ab28717 100644
--- a/tests/libqos/virtio-pci.c
+++ b/tests/libqos/virtio-pci.c
@@ -36,6 +36,8 @@ static QVirtioPCIDevice *qpcidevice_to_qvirtiodevice(QPCIDevice *pdev)
                             qpci_config_readw(vpcidev->pdev, PCI_SUBSYSTEM_ID);
     }
 
+    vpcidev->config_msix_entry = -1;
+
     return vpcidev;
 }
 
@@ -125,10 +127,45 @@ static void qvirtio_pci_set_status(QVirtioDevice *d, uint8_t status)
     qpci_io_writeb(dev->pdev, dev->addr + QVIRTIO_DEVICE_STATUS, status);
 }
 
-static uint8_t qvirtio_pci_get_isr_status(QVirtioDevice *d)
+static bool qvirtio_pci_get_queue_isr_status(QVirtioDevice *d, QVirtQueue *vq)
 {
     QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
-    return qpci_io_readb(dev->pdev, dev->addr + QVIRTIO_ISR_STATUS);
+    QVirtQueuePCI *vqpci = (QVirtQueuePCI *)vq;
+    uint32_t data;
+
+    if (dev->pdev->msix_enabled) {
+        g_assert_cmpint(vqpci->msix_entry, !=, -1);
+        if (qpci_msix_masked(dev->pdev, vqpci->msix_entry)) {
+            /* No ISR checking should be done if masked, but read anyway */
+            return qpci_msix_pending(dev->pdev, vqpci->msix_entry);
+        } else {
+            data = readl(vqpci->msix_addr);
+            writel(vqpci->msix_addr, 0);
+            return data == vqpci->msix_data;
+        }
+    } else {
+        return qpci_io_readb(dev->pdev, dev->addr + QVIRTIO_ISR_STATUS) & 1;
+    }
+}
+
+static bool qvirtio_pci_get_config_isr_status(QVirtioDevice *d)
+{
+    QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
+    uint32_t data;
+
+    if (dev->pdev->msix_enabled) {
+        g_assert_cmpint(dev->config_msix_entry, !=, -1);
+        if (qpci_msix_masked(dev->pdev, dev->config_msix_entry)) {
+            /* No ISR checking should be done if masked, but read anyway */
+            return qpci_msix_pending(dev->pdev, dev->config_msix_entry);
+        } else {
+            data = readl(dev->config_msix_addr);
+            writel(dev->config_msix_addr, 0);
+            return data == dev->config_msix_data;
+        }
+    } else {
+        return qpci_io_readb(dev->pdev, dev->addr + QVIRTIO_ISR_STATUS) & 2;
+    }
 }
 
 static void qvirtio_pci_queue_select(QVirtioDevice *d, uint16_t index)
@@ -154,32 +191,34 @@ static QVirtQueue *qvirtio_pci_virtqueue_setup(QVirtioDevice *d,
 {
     uint32_t feat;
     uint64_t addr;
-    QVirtQueue *vq;
+    QVirtQueuePCI *vqpci;
 
-    vq = g_malloc0(sizeof(*vq));
+    vqpci = g_malloc0(sizeof(*vqpci));
     feat = qvirtio_pci_get_guest_features(d);
 
     qvirtio_pci_queue_select(d, index);
-    vq->index = index;
-    vq->size = qvirtio_pci_get_queue_size(d);
-    vq->free_head = 0;
-    vq->num_free = vq->size;
-    vq->align = QVIRTIO_PCI_ALIGN;
-    vq->indirect = (feat & QVIRTIO_F_RING_INDIRECT_DESC) != 0;
+    vqpci->vq.index = index;
+    vqpci->vq.size = qvirtio_pci_get_queue_size(d);
+    vqpci->vq.free_head = 0;
+    vqpci->vq.num_free = vqpci->vq.size;
+    vqpci->vq.align = QVIRTIO_PCI_ALIGN;
+    vqpci->vq.indirect = (feat & QVIRTIO_F_RING_INDIRECT_DESC) != 0;
+
+    vqpci->msix_entry = -1;
+    vqpci->msix_addr = 0;
+    vqpci->msix_data = 0x12345678;
 
     /* Check different than 0 */
-    g_assert_cmpint(vq->size, !=, 0);
+    g_assert_cmpint(vqpci->vq.size, !=, 0);
 
     /* Check power of 2 */
-    g_assert_cmpint(vq->size & (vq->size - 1), ==, 0);
-
-    addr = guest_alloc(alloc, qvring_size(vq->size, QVIRTIO_PCI_ALIGN));
-    qvring_init(alloc, vq, addr);
-    qvirtio_pci_set_queue_address(d, vq->desc / QVIRTIO_PCI_ALIGN);
+    g_assert_cmpint(vqpci->vq.size & (vqpci->vq.size - 1), ==, 0);
 
-    /* TODO: MSI-X configuration */
+    addr = guest_alloc(alloc, qvring_size(vqpci->vq.size, QVIRTIO_PCI_ALIGN));
+    qvring_init(alloc, &vqpci->vq, addr);
+    qvirtio_pci_set_queue_address(d, vqpci->vq.desc / QVIRTIO_PCI_ALIGN);
 
-    return vq;
+    return &vqpci->vq;
 }
 
 static void qvirtio_pci_virtqueue_kick(QVirtioDevice *d, QVirtQueue *vq)
@@ -198,7 +237,8 @@ const QVirtioBus qvirtio_pci = {
     .get_guest_features = qvirtio_pci_get_guest_features,
     .get_status = qvirtio_pci_get_status,
     .set_status = qvirtio_pci_set_status,
-    .get_isr_status = qvirtio_pci_get_isr_status,
+    .get_queue_isr_status = qvirtio_pci_get_queue_isr_status,
+    .get_config_isr_status = qvirtio_pci_get_config_isr_status,
     .queue_select = qvirtio_pci_queue_select,
     .get_queue_size = qvirtio_pci_get_queue_size,
     .set_queue_address = qvirtio_pci_set_queue_address,
@@ -235,4 +275,68 @@ void qvirtio_pci_device_enable(QVirtioPCIDevice *d)
 void qvirtio_pci_device_disable(QVirtioPCIDevice *d)
 {
     qpci_iounmap(d->pdev, d->addr);
+    d->addr = NULL;
+}
+
+void qvirtqueue_pci_msix_setup(QVirtioPCIDevice *d, QVirtQueuePCI *vqpci,
+                                        QGuestAllocator *alloc, uint16_t entry)
+{
+    uint16_t vector;
+    uint32_t control;
+    void *addr;
+
+    g_assert(d->pdev->msix_enabled);
+    addr = d->pdev->msix_table + (entry * 16);
+
+    g_assert_cmpint(entry, >=, 0);
+    g_assert_cmpint(entry, <, qpci_msix_table_size(d->pdev));
+    vqpci->msix_entry = entry;
+
+    vqpci->msix_addr = guest_alloc(alloc, 4);
+    qpci_io_writel(d->pdev, addr + PCI_MSIX_ENTRY_LOWER_ADDR,
+                                                    vqpci->msix_addr & ~0UL);
+    qpci_io_writel(d->pdev, addr + PCI_MSIX_ENTRY_UPPER_ADDR,
+                                            (vqpci->msix_addr >> 32) & ~0UL);
+    qpci_io_writel(d->pdev, addr + PCI_MSIX_ENTRY_DATA, vqpci->msix_data);
+
+    control = qpci_io_readl(d->pdev, addr + PCI_MSIX_ENTRY_VECTOR_CTRL);
+    qpci_io_writel(d->pdev, addr + PCI_MSIX_ENTRY_VECTOR_CTRL,
+                                        control & ~PCI_MSIX_ENTRY_CTRL_MASKBIT);
+
+    qvirtio_pci_queue_select(&d->vdev, vqpci->vq.index);
+    qpci_io_writew(d->pdev, d->addr + QVIRTIO_MSIX_QUEUE_VECTOR, entry);
+    vector = qpci_io_readw(d->pdev, d->addr + QVIRTIO_MSIX_QUEUE_VECTOR);
+    g_assert_cmphex(vector, !=, QVIRTIO_MSI_NO_VECTOR);
+}
+
+void qvirtio_pci_set_msix_configuration_vector(QVirtioPCIDevice *d,
+                                        QGuestAllocator *alloc, uint16_t entry)
+{
+    uint16_t vector;
+    uint32_t control;
+    void *addr;
+
+    g_assert(d->pdev->msix_enabled);
+    addr = d->pdev->msix_table + (entry * 16);
+
+    g_assert_cmpint(entry, >=, 0);
+    g_assert_cmpint(entry, <, qpci_msix_table_size(d->pdev));
+    d->config_msix_entry = entry;
+
+    d->config_msix_data = 0x12345678;
+    d->config_msix_addr = guest_alloc(alloc, 4);
+
+    qpci_io_writel(d->pdev, addr + PCI_MSIX_ENTRY_LOWER_ADDR,
+                                                    d->config_msix_addr & ~0UL);
+    qpci_io_writel(d->pdev, addr + PCI_MSIX_ENTRY_UPPER_ADDR,
+                                            (d->config_msix_addr >> 32) & ~0UL);
+    qpci_io_writel(d->pdev, addr + PCI_MSIX_ENTRY_DATA, d->config_msix_data);
+
+    control = qpci_io_readl(d->pdev, addr + PCI_MSIX_ENTRY_VECTOR_CTRL);
+    qpci_io_writel(d->pdev, addr + PCI_MSIX_ENTRY_VECTOR_CTRL,
+                                        control & ~PCI_MSIX_ENTRY_CTRL_MASKBIT);
+
+    qpci_io_writew(d->pdev, d->addr + QVIRTIO_MSIX_CONF_VECTOR, entry);
+    vector = qpci_io_readw(d->pdev, d->addr + QVIRTIO_MSIX_CONF_VECTOR);
+    g_assert_cmphex(vector, !=, QVIRTIO_MSI_NO_VECTOR);
 }
diff --git a/tests/libqos/virtio-pci.h b/tests/libqos/virtio-pci.h
index 40bd12d..883f7ff 100644
--- a/tests/libqos/virtio-pci.h
+++ b/tests/libqos/virtio-pci.h
@@ -28,12 +28,24 @@
 
 #define QVIRTIO_PCI_ALIGN   4096
 
+#define QVIRTIO_MSI_NO_VECTOR   0xFFFF
+
 typedef struct QVirtioPCIDevice {
     QVirtioDevice vdev;
     QPCIDevice *pdev;
     void *addr;
+    uint16_t config_msix_entry;
+    uint64_t config_msix_addr;
+    uint32_t config_msix_data;
 } QVirtioPCIDevice;
 
+typedef struct QVirtQueuePCI {
+    QVirtQueue vq;
+    uint16_t msix_entry;
+    uint64_t msix_addr;
+    uint32_t msix_data;
+} QVirtQueuePCI;
+
 extern const QVirtioBus qvirtio_pci;
 
 void qvirtio_pci_foreach(QPCIBus *bus, uint16_t device_type,
@@ -41,4 +53,9 @@ void qvirtio_pci_foreach(QPCIBus *bus, uint16_t device_type,
 QVirtioPCIDevice *qvirtio_pci_device_find(QPCIBus *bus, uint16_t device_type);
 void qvirtio_pci_device_enable(QVirtioPCIDevice *d);
 void qvirtio_pci_device_disable(QVirtioPCIDevice *d);
+
+void qvirtio_pci_set_msix_configuration_vector(QVirtioPCIDevice *d,
+                                        QGuestAllocator *alloc, uint16_t entry);
+void qvirtqueue_pci_msix_setup(QVirtioPCIDevice *d, QVirtQueuePCI *vqpci,
+                                        QGuestAllocator *alloc, uint16_t entry);
 #endif
diff --git a/tests/libqos/virtio.c b/tests/libqos/virtio.c
index b1cab1f..16eaf79 100644
--- a/tests/libqos/virtio.c
+++ b/tests/libqos/virtio.c
@@ -78,12 +78,25 @@ void qvirtio_set_driver_ok(const QVirtioBus *bus, QVirtioDevice *d)
                 QVIRTIO_DRIVER_OK | QVIRTIO_DRIVER | QVIRTIO_ACKNOWLEDGE);
 }
 
-bool qvirtio_wait_isr(const QVirtioBus *bus, QVirtioDevice *d, uint8_t mask,
+bool qvirtio_wait_queue_isr(const QVirtioBus *bus, QVirtioDevice *d,
+                                            QVirtQueue *vq, uint64_t timeout)
+{
+    do {
+        clock_step(10);
+        if (bus->get_queue_isr_status(d, vq)) {
+            break; /* It has ended */
+        }
+    } while (--timeout);
+
+    return timeout != 0;
+}
+
+bool qvirtio_wait_config_isr(const QVirtioBus *bus, QVirtioDevice *d,
                                                             uint64_t timeout)
 {
     do {
         clock_step(10);
-        if (bus->get_isr_status(d) & mask) {
+        if (bus->get_config_isr_status(d)) {
             break; /* It has ended */
         }
     } while (--timeout);
diff --git a/tests/libqos/virtio.h b/tests/libqos/virtio.h
index 1860660..cebccd2 100644
--- a/tests/libqos/virtio.h
+++ b/tests/libqos/virtio.h
@@ -109,8 +109,11 @@ typedef struct QVirtioBus {
     /* Set status of the device  */
     void (*set_status)(QVirtioDevice *d, uint8_t status);
 
-    /* Get the ISR status of the device */
-    uint8_t (*get_isr_status)(QVirtioDevice *d);
+    /* Get the queue ISR status of the device */
+    bool (*get_queue_isr_status)(QVirtioDevice *d, QVirtQueue *vq);
+
+    /* Get the configuration ISR status of the device */
+    bool (*get_config_isr_status)(QVirtioDevice *d);
 
     /* Select a queue to work on */
     void (*queue_select)(QVirtioDevice *d, uint16_t index);
@@ -153,7 +156,9 @@ void qvirtio_set_acknowledge(const QVirtioBus *bus, QVirtioDevice *d);
 void qvirtio_set_driver(const QVirtioBus *bus, QVirtioDevice *d);
 void qvirtio_set_driver_ok(const QVirtioBus *bus, QVirtioDevice *d);
 
-bool qvirtio_wait_isr(const QVirtioBus *bus, QVirtioDevice *d, uint8_t mask,
+bool qvirtio_wait_queue_isr(const QVirtioBus *bus, QVirtioDevice *d,
+                                            QVirtQueue *vq, uint64_t timeout);
+bool qvirtio_wait_config_isr(const QVirtioBus *bus, QVirtioDevice *d,
                                                             uint64_t timeout);
 QVirtQueue *qvirtqueue_setup(const QVirtioBus *bus, QVirtioDevice *d,
                                         QGuestAllocator *alloc, uint16_t index);
diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
index 672580b..0100aaa 100644
--- a/tests/virtio-blk-test.c
+++ b/tests/virtio-blk-test.c
@@ -134,7 +134,7 @@ static void pci_basic(void)
 {
     QVirtioPCIDevice *dev;
     QPCIBus *bus;
-    QVirtQueue *vq;
+    QVirtQueuePCI *vqpci;
     QGuestAllocator *alloc;
     QVirtioBlkReq req;
     void *addr;
@@ -162,7 +162,8 @@ static void pci_basic(void)
     qvirtio_set_features(&qvirtio_pci, &dev->vdev, features);
 
     alloc = pc_alloc_init();
-    vq = qvirtqueue_setup(&qvirtio_pci, &dev->vdev, alloc, 0);
+    vqpci = (QVirtQueuePCI *)qvirtqueue_setup(&qvirtio_pci, &dev->vdev,
+                                                                    alloc, 0);
 
     qvirtio_set_driver_ok(&qvirtio_pci, &dev->vdev);
 
@@ -178,11 +179,11 @@ static void pci_basic(void)
 
     g_free(req.data);
 
-    free_head = qvirtqueue_add(vq, req_addr, 528, false, true);
-    qvirtqueue_add(vq, req_addr + 528, 1, true, false);
-    qvirtqueue_kick(&qvirtio_pci, &dev->vdev, vq, free_head);
+    free_head = qvirtqueue_add(&vqpci->vq, req_addr, 528, false, true);
+    qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false);
+    qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
 
-    g_assert(qvirtio_wait_isr(&qvirtio_pci, &dev->vdev, 0x1,
+    g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
                                                         QVIRTIO_BLK_TIMEOUT));
     status = readb(req_addr + 528);
     g_assert_cmpint(status, ==, 0);
@@ -199,12 +200,12 @@ static void pci_basic(void)
 
     g_free(req.data);
 
-    free_head = qvirtqueue_add(vq, req_addr, 16, false, true);
-    qvirtqueue_add(vq, req_addr + 16, 513, true, false);
+    free_head = qvirtqueue_add(&vqpci->vq, req_addr, 16, false, true);
+    qvirtqueue_add(&vqpci->vq, req_addr + 16, 513, true, false);
 
-    qvirtqueue_kick(&qvirtio_pci, &dev->vdev, vq, free_head);
+    qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
 
-    g_assert(qvirtio_wait_isr(&qvirtio_pci, &dev->vdev, 0x1,
+    g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
                                                         QVIRTIO_BLK_TIMEOUT));
     status = readb(req_addr + 528);
     g_assert_cmpint(status, ==, 0);
@@ -226,15 +227,13 @@ static void pci_basic(void)
 
     req_addr = virtio_blk_request(alloc, &req, 512);
 
-    g_free(req.data);
-
-    free_head = qvirtqueue_add(vq, req_addr, 16, false, true);
-    qvirtqueue_add(vq, req_addr + 16, 512, false, true);
-    qvirtqueue_add(vq, req_addr + 528, 1, true, false);
+    free_head = qvirtqueue_add(&vqpci->vq, req_addr, 16, false, true);
+    qvirtqueue_add(&vqpci->vq, req_addr + 16, 512, false, true);
+    qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false);
 
-    qvirtqueue_kick(&qvirtio_pci, &dev->vdev, vq, free_head);
+    qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
 
-    g_assert(qvirtio_wait_isr(&qvirtio_pci, &dev->vdev, 0x1,
+    g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
                                                         QVIRTIO_BLK_TIMEOUT));
     status = readb(req_addr + 528);
     g_assert_cmpint(status, ==, 0);
@@ -251,19 +250,17 @@ static void pci_basic(void)
 
     g_free(req.data);
 
-    free_head = qvirtqueue_add(vq, req_addr, 16, false, true);
-    qvirtqueue_add(vq, req_addr + 16, 512, true, true);
-    qvirtqueue_add(vq, req_addr + 528, 1, true, false);
+    free_head = qvirtqueue_add(&vqpci->vq, req_addr, 16, false, true);
+    qvirtqueue_add(&vqpci->vq, req_addr + 16, 512, true, true);
+    qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false);
 
-    qvirtqueue_kick(&qvirtio_pci, &dev->vdev, vq, free_head);
+    qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
 
-    g_assert(qvirtio_wait_isr(&qvirtio_pci, &dev->vdev, 0x1,
+    g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
                                                         QVIRTIO_BLK_TIMEOUT));
     status = readb(req_addr + 528);
     g_assert_cmpint(status, ==, 0);
 
-    guest_free(alloc, req_addr);
-
     data = g_malloc0(512);
     memread(req_addr + 16, data, 512);
     g_assert_cmpstr(data, ==, "TEST");
@@ -272,7 +269,7 @@ static void pci_basic(void)
     guest_free(alloc, req_addr);
 
     /* End test */
-    guest_free(alloc, vq->desc);
+    guest_free(alloc, vqpci->vq.desc);
     qvirtio_pci_device_disable(dev);
     g_free(dev);
     test_end();
@@ -282,7 +279,7 @@ static void pci_indirect(void)
 {
     QVirtioPCIDevice *dev;
     QPCIBus *bus;
-    QVirtQueue *vq;
+    QVirtQueuePCI *vqpci;
     QGuestAllocator *alloc;
     QVirtioBlkReq req;
     QVRingIndirectDesc *indirect;
@@ -311,8 +308,8 @@ static void pci_indirect(void)
     qvirtio_set_features(&qvirtio_pci, &dev->vdev, features);
 
     alloc = pc_alloc_init();
-    vq = qvirtqueue_setup(&qvirtio_pci, &dev->vdev, alloc, 0);
-
+    vqpci = (QVirtQueuePCI *)qvirtqueue_setup(&qvirtio_pci, &dev->vdev,
+                                                                    alloc, 0);
     qvirtio_set_driver_ok(&qvirtio_pci, &dev->vdev);
 
     /* Write request */
@@ -329,10 +326,10 @@ static void pci_indirect(void)
     indirect = qvring_indirect_desc_setup(&dev->vdev, alloc, 2);
     qvring_indirect_desc_add(indirect, req_addr, 528, false);
     qvring_indirect_desc_add(indirect, req_addr + 528, 1, true);
-    free_head = qvirtqueue_add_indirect(vq, indirect);
-    qvirtqueue_kick(&qvirtio_pci, &dev->vdev, vq, free_head);
+    free_head = qvirtqueue_add_indirect(&vqpci->vq, indirect);
+    qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
 
-    g_assert(qvirtio_wait_isr(&qvirtio_pci, &dev->vdev, 0x1,
+    g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
                                                         QVIRTIO_BLK_TIMEOUT));
     status = readb(req_addr + 528);
     g_assert_cmpint(status, ==, 0);
@@ -354,10 +351,10 @@ static void pci_indirect(void)
     indirect = qvring_indirect_desc_setup(&dev->vdev, alloc, 2);
     qvring_indirect_desc_add(indirect, req_addr, 16, false);
     qvring_indirect_desc_add(indirect, req_addr + 16, 513, true);
-    free_head = qvirtqueue_add_indirect(vq, indirect);
-    qvirtqueue_kick(&qvirtio_pci, &dev->vdev, vq, free_head);
+    free_head = qvirtqueue_add_indirect(&vqpci->vq, indirect);
+    qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
 
-    g_assert(qvirtio_wait_isr(&qvirtio_pci, &dev->vdev, 0x1,
+    g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
                                                         QVIRTIO_BLK_TIMEOUT));
     status = readb(req_addr + 528);
     g_assert_cmpint(status, ==, 0);
@@ -371,7 +368,7 @@ static void pci_indirect(void)
     guest_free(alloc, req_addr);
 
     /* End test */
-    guest_free(alloc, vq->desc);
+    guest_free(alloc, vqpci->vq.desc);
     qvirtio_pci_device_disable(dev);
     g_free(dev);
     test_end();
@@ -399,7 +396,7 @@ static void pci_config(void)
 
     qmp("{ 'execute': 'block_resize', 'arguments': { 'device': 'drive0', "
                                                     " 'size': %d } }", n_size);
-    g_assert(qvirtio_wait_isr(&qvirtio_pci, &dev->vdev, 0x2,
+    g_assert(qvirtio_wait_config_isr(&qvirtio_pci, &dev->vdev,
                                                         QVIRTIO_BLK_TIMEOUT));
 
     capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev, addr);
@@ -410,6 +407,116 @@ static void pci_config(void)
     test_end();
 }
 
+static void pci_msix(void)
+{
+    QVirtioPCIDevice *dev;
+    QPCIBus *bus;
+    QVirtQueuePCI *vqpci;
+    QGuestAllocator *alloc;
+    QVirtioBlkReq req;
+    int n_size = TEST_IMAGE_SIZE / 2;
+    void *addr;
+    uint64_t req_addr;
+    uint64_t capacity;
+    uint32_t features;
+    uint32_t free_head;
+    uint8_t status;
+    char *data;
+
+    bus = test_start();
+    alloc = pc_alloc_init();
+
+    dev = virtio_blk_init(bus);
+    qpci_msix_enable(dev->pdev);
+
+    qvirtio_pci_set_msix_configuration_vector(dev, alloc, 0);
+
+    /* MSI-X is enabled */
+    addr = dev->addr + QVIRTIO_DEVICE_SPECIFIC_MSIX;
+
+    capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev, addr);
+    g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
+
+    features = qvirtio_get_features(&qvirtio_pci, &dev->vdev);
+    features = features & ~(QVIRTIO_F_BAD_FEATURE |
+                            QVIRTIO_F_RING_INDIRECT_DESC |
+                            QVIRTIO_F_RING_EVENT_IDX | QVIRTIO_BLK_F_SCSI);
+    qvirtio_set_features(&qvirtio_pci, &dev->vdev, features);
+
+    vqpci = (QVirtQueuePCI *)qvirtqueue_setup(&qvirtio_pci, &dev->vdev,
+                                                                    alloc, 0);
+    qvirtqueue_pci_msix_setup(dev, vqpci, alloc, 1);
+
+    qvirtio_set_driver_ok(&qvirtio_pci, &dev->vdev);
+
+    qmp("{ 'execute': 'block_resize', 'arguments': { 'device': 'drive0', "
+                                                    " 'size': %d } }", n_size);
+
+    g_assert(qvirtio_wait_config_isr(&qvirtio_pci, &dev->vdev,
+                                                        QVIRTIO_BLK_TIMEOUT));
+
+    capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev, addr);
+    g_assert_cmpint(capacity, ==, n_size / 512);
+
+    /* Write request */
+    req.type = QVIRTIO_BLK_T_OUT;
+    req.ioprio = 1;
+    req.sector = 0;
+    req.data = g_malloc0(512);
+    strcpy(req.data, "TEST");
+
+    req_addr = virtio_blk_request(alloc, &req, 512);
+
+    g_free(req.data);
+
+    free_head = qvirtqueue_add(&vqpci->vq, req_addr, 528, false, true);
+    qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false);
+    qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
+
+    g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
+                                                        QVIRTIO_BLK_TIMEOUT));
+
+    status = readb(req_addr + 528);
+    g_assert_cmpint(status, ==, 0);
+
+    guest_free(alloc, req_addr);
+
+    /* Read request */
+    req.type = QVIRTIO_BLK_T_IN;
+    req.ioprio = 1;
+    req.sector = 0;
+    req.data = g_malloc0(512);
+
+    req_addr = virtio_blk_request(alloc, &req, 512);
+
+    g_free(req.data);
+
+    free_head = qvirtqueue_add(&vqpci->vq, req_addr, 16, false, true);
+    qvirtqueue_add(&vqpci->vq, req_addr + 16, 513, true, false);
+
+    qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
+
+    g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
+                                                        QVIRTIO_BLK_TIMEOUT));
+
+    status = readb(req_addr + 528);
+    g_assert_cmpint(status, ==, 0);
+
+    data = g_malloc0(512);
+    memread(req_addr + 16, data, 512);
+    g_assert_cmpstr(data, ==, "TEST");
+    g_free(data);
+
+    guest_free(alloc, req_addr);
+
+    /* End test */
+    guest_free(alloc, vqpci->vq.desc);
+    qpci_msix_disable(dev->pdev);
+    qvirtio_pci_device_disable(dev);
+    g_free(dev);
+    test_end();
+}
+
 int main(int argc, char **argv)
 {
     int ret;
@@ -419,6 +526,7 @@ int main(int argc, char **argv)
     g_test_add_func("/virtio/blk/pci/basic", pci_basic);
     g_test_add_func("/virtio/blk/pci/indirect", pci_indirect);
     g_test_add_func("/virtio/blk/pci/config", pci_config);
+    g_test_add_func("/virtio/blk/pci/msix", pci_msix);
 
     ret = g_test_run();
 
-- 
1.9.3

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

* [Qemu-devel] [PULL 12/26] libqos: Added EVENT_IDX support
  2014-09-05 16:13 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (10 preceding siblings ...)
  2014-09-05 16:13 ` [Qemu-devel] [PULL 11/26] libqos: Added MSI-X support Stefan Hajnoczi
@ 2014-09-05 16:13 ` Stefan Hajnoczi
  2014-09-05 16:13 ` [Qemu-devel] [PULL 13/26] qemu-img: clarify src_cache option documentation Stefan Hajnoczi
                   ` (14 subsequent siblings)
  26 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2014-09-05 16:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marc Marí, Peter Maydell, Stefan Hajnoczi

From: Marc Marí <marc.mari.barcelo@gmail.com>

Added avail_event and NO_NOTIFY check before notifying.
Added used_event setting.

Signed-off-by: Marc Marí <marc.mari.barcelo@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 tests/libqos/virtio-pci.c |   1 +
 tests/libqos/virtio.c     |  27 +++++++++-
 tests/libqos/virtio.h     |   5 ++
 tests/virtio-blk-test.c   | 124 ++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 156 insertions(+), 1 deletion(-)

diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c
index ab28717..788ebaf 100644
--- a/tests/libqos/virtio-pci.c
+++ b/tests/libqos/virtio-pci.c
@@ -203,6 +203,7 @@ static QVirtQueue *qvirtio_pci_virtqueue_setup(QVirtioDevice *d,
     vqpci->vq.num_free = vqpci->vq.size;
     vqpci->vq.align = QVIRTIO_PCI_ALIGN;
     vqpci->vq.indirect = (feat & QVIRTIO_F_RING_INDIRECT_DESC) != 0;
+    vqpci->vq.event = (feat & QVIRTIO_F_RING_EVENT_IDX) != 0;
 
     vqpci->msix_entry = -1;
     vqpci->msix_addr = 0;
diff --git a/tests/libqos/virtio.c b/tests/libqos/virtio.c
index 16eaf79..128dbd0 100644
--- a/tests/libqos/virtio.c
+++ b/tests/libqos/virtio.c
@@ -124,9 +124,13 @@ void qvring_init(const QGuestAllocator *alloc, QVirtQueue *vq, uint64_t addr)
     writew(vq->avail, 0);
     /* vq->avail->idx */
     writew(vq->avail + 2, 0);
+    /* vq->avail->used_event */
+    writew(vq->avail + 4 + (2 * vq->size), 0);
 
     /* vq->used->flags */
     writew(vq->used, 0);
+    /* vq->used->avail_event */
+    writew(vq->used+2+(sizeof(struct QVRingUsedElem)*vq->size), 0);
 }
 
 QVRingIndirectDesc *qvring_indirect_desc_setup(QVirtioDevice *d,
@@ -222,11 +226,32 @@ void qvirtqueue_kick(const QVirtioBus *bus, QVirtioDevice *d, QVirtQueue *vq,
 {
     /* vq->avail->idx */
     uint16_t idx = readl(vq->avail + 2);
+    /* vq->used->flags */
+    uint16_t flags;
+    /* vq->used->avail_event */
+    uint16_t avail_event;
 
     /* vq->avail->ring[idx % vq->size] */
     writel(vq->avail + 4 + (2 * (idx % vq->size)), free_head);
     /* vq->avail->idx */
     writel(vq->avail + 2, idx + 1);
 
-    bus->virtqueue_kick(d, vq);
+    /* Must read after idx is updated */
+    flags = readw(vq->avail);
+    avail_event = readw(vq->used + 4 +
+                                (sizeof(struct QVRingUsedElem) * vq->size));
+
+    /* < 1 because we add elements to avail queue one by one */
+    if ((flags & QVRING_USED_F_NO_NOTIFY) == 0 &&
+                            (!vq->event || (uint16_t)(idx-avail_event) < 1)) {
+        bus->virtqueue_kick(d, vq);
+    }
+}
+
+void qvirtqueue_set_used_event(QVirtQueue *vq, uint16_t idx)
+{
+    g_assert(vq->event);
+
+    /* vq->avail->used_event */
+    writew(vq->avail + 4 + (2 * vq->size), idx);
 }
diff --git a/tests/libqos/virtio.h b/tests/libqos/virtio.h
index cebccd2..70b3376 100644
--- a/tests/libqos/virtio.h
+++ b/tests/libqos/virtio.h
@@ -26,6 +26,7 @@
 #define QVIRTIO_F_ANY_LAYOUT            0x08000000
 #define QVIRTIO_F_RING_INDIRECT_DESC    0x10000000
 #define QVIRTIO_F_RING_EVENT_IDX        0x20000000
+#define QVIRTIO_F_BAD_FEATURE           0x40000000
 
 #define QVRING_DESC_F_NEXT      0x1
 #define QVRING_DESC_F_WRITE     0x2
@@ -57,6 +58,7 @@ typedef struct QVRingAvail {
     uint16_t flags;
     uint16_t idx;
     uint16_t ring[0]; /* This is an array of uint16_t */
+    uint16_t used_event;
 } QVRingAvail;
 
 typedef struct QVRingUsedElem {
@@ -68,6 +70,7 @@ typedef struct QVRingUsed {
     uint16_t flags;
     uint16_t idx;
     QVRingUsedElem ring[0]; /* This is an array of QVRingUsedElem structs */
+    uint16_t avail_event;
 } QVRingUsed;
 
 typedef struct QVirtQueue {
@@ -80,6 +83,7 @@ typedef struct QVirtQueue {
     uint32_t num_free;
     uint32_t align;
     bool indirect;
+    bool event;
 } QVirtQueue;
 
 typedef struct QVRingIndirectDesc {
@@ -174,4 +178,5 @@ uint32_t qvirtqueue_add_indirect(QVirtQueue *vq, QVRingIndirectDesc *indirect);
 void qvirtqueue_kick(const QVirtioBus *bus, QVirtioDevice *d, QVirtQueue *vq,
                                                             uint32_t free_head);
 
+void qvirtqueue_set_used_event(QVirtQueue *vq, uint16_t idx);
 #endif
diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
index 0100aaa..588666c 100644
--- a/tests/virtio-blk-test.c
+++ b/tests/virtio-blk-test.c
@@ -496,6 +496,129 @@ static void pci_msix(void)
 
     qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
 
+
+    g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
+                                                        QVIRTIO_BLK_TIMEOUT));
+
+    status = readb(req_addr + 528);
+    g_assert_cmpint(status, ==, 0);
+
+    data = g_malloc0(512);
+    memread(req_addr + 16, data, 512);
+    g_assert_cmpstr(data, ==, "TEST");
+    g_free(data);
+
+    guest_free(alloc, req_addr);
+
+    /* End test */
+    guest_free(alloc, (uint64_t)vqpci->vq.desc);
+    qpci_msix_disable(dev->pdev);
+    qvirtio_pci_device_disable(dev);
+    g_free(dev);
+    test_end();
+}
+
+static void pci_idx(void)
+{
+    QVirtioPCIDevice *dev;
+    QPCIBus *bus;
+    QVirtQueuePCI *vqpci;
+    QGuestAllocator *alloc;
+    QVirtioBlkReq req;
+    void *addr;
+    uint64_t req_addr;
+    uint64_t capacity;
+    uint32_t features;
+    uint32_t free_head;
+    uint8_t status;
+    char *data;
+
+    bus = test_start();
+    alloc = pc_alloc_init();
+
+    dev = virtio_blk_init(bus);
+    qpci_msix_enable(dev->pdev);
+
+    qvirtio_pci_set_msix_configuration_vector(dev, alloc, 0);
+
+    /* MSI-X is enabled */
+    addr = dev->addr + QVIRTIO_DEVICE_SPECIFIC_MSIX;
+
+    capacity = qvirtio_config_readq(&qvirtio_pci, &dev->vdev, addr);
+    g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
+
+    features = qvirtio_get_features(&qvirtio_pci, &dev->vdev);
+    features = features & ~(QVIRTIO_F_BAD_FEATURE |
+                            QVIRTIO_F_RING_INDIRECT_DESC |
+                            QVIRTIO_F_NOTIFY_ON_EMPTY | QVIRTIO_BLK_F_SCSI);
+    qvirtio_set_features(&qvirtio_pci, &dev->vdev, features);
+
+    vqpci = (QVirtQueuePCI *)qvirtqueue_setup(&qvirtio_pci, &dev->vdev,
+                                                                    alloc, 0);
+    qvirtqueue_pci_msix_setup(dev, vqpci, alloc, 1);
+
+    qvirtio_set_driver_ok(&qvirtio_pci, &dev->vdev);
+
+    /* Write request */
+    req.type = QVIRTIO_BLK_T_OUT;
+    req.ioprio = 1;
+    req.sector = 0;
+    req.data = g_malloc0(512);
+    strcpy(req.data, "TEST");
+
+    req_addr = virtio_blk_request(alloc, &req, 512);
+
+    g_free(req.data);
+
+    free_head = qvirtqueue_add(&vqpci->vq, req_addr, 528, false, true);
+    qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false);
+    qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
+
+    g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
+                                                        QVIRTIO_BLK_TIMEOUT));
+
+    /* Write request */
+    req.type = QVIRTIO_BLK_T_OUT;
+    req.ioprio = 1;
+    req.sector = 1;
+    req.data = g_malloc0(512);
+    strcpy(req.data, "TEST");
+
+    req_addr = virtio_blk_request(alloc, &req, 512);
+
+    g_free(req.data);
+
+    /* Notify after processing the third request */
+    qvirtqueue_set_used_event(&vqpci->vq, 2);
+    free_head = qvirtqueue_add(&vqpci->vq, req_addr, 528, false, true);
+    qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false);
+    qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
+
+    /* No notification expected */
+    g_assert(!qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
+                                                        QVIRTIO_BLK_TIMEOUT));
+
+    status = readb(req_addr + 528);
+    g_assert_cmpint(status, ==, 0);
+
+    guest_free(alloc, req_addr);
+
+    /* Read request */
+    req.type = QVIRTIO_BLK_T_IN;
+    req.ioprio = 1;
+    req.sector = 1;
+    req.data = g_malloc0(512);
+
+    req_addr = virtio_blk_request(alloc, &req, 512);
+
+    g_free(req.data);
+
+    free_head = qvirtqueue_add(&vqpci->vq, req_addr, 16, false, true);
+    qvirtqueue_add(&vqpci->vq, req_addr + 16, 513, true, false);
+
+    qvirtqueue_kick(&qvirtio_pci, &dev->vdev, &vqpci->vq, free_head);
+
+
     g_assert(qvirtio_wait_queue_isr(&qvirtio_pci, &dev->vdev, &vqpci->vq,
                                                         QVIRTIO_BLK_TIMEOUT));
 
@@ -527,6 +650,7 @@ int main(int argc, char **argv)
     g_test_add_func("/virtio/blk/pci/indirect", pci_indirect);
     g_test_add_func("/virtio/blk/pci/config", pci_config);
     g_test_add_func("/virtio/blk/pci/msix", pci_msix);
+    g_test_add_func("/virtio/blk/pci/idx", pci_idx);
 
     ret = g_test_run();
 
-- 
1.9.3

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

* [Qemu-devel] [PULL 13/26] qemu-img: clarify src_cache option documentation
  2014-09-05 16:13 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (11 preceding siblings ...)
  2014-09-05 16:13 ` [Qemu-devel] [PULL 12/26] libqos: Added EVENT_IDX support Stefan Hajnoczi
@ 2014-09-05 16:13 ` Stefan Hajnoczi
  2014-09-05 16:13 ` [Qemu-devel] [PULL 14/26] qemu-img: fix rebase " Stefan Hajnoczi
                   ` (13 subsequent siblings)
  26 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2014-09-05 16:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Stefan Hajnoczi

The source cache option takes the same values as the cache option.  The
documentation reads a little strange because it starts with "In contrast
the src_cache option ...".  The fact that this is comparing with the
previous documented option (the 'cache' option) is implicit.  Readers
may be confused, especially if they jump to src_cache without reading
cache documentation first.

Suggested-by: Jeff Nelson <jenelson@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
---
 qemu-img.c    | 3 ++-
 qemu-img.texi | 5 +++--
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index ff29ed1..91d1ac3 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -95,7 +95,8 @@ static void QEMU_NORETURN help(void)
            "  'cache' is the cache mode used to write the output disk image, the valid\n"
            "    options are: 'none', 'writeback' (default, except for convert), 'writethrough',\n"
            "    'directsync' and 'unsafe' (default for convert)\n"
-           "  'src_cache' in contrast is the cache mode used to read input disk images\n"
+           "  'src_cache' is the cache mode used to read input disk images, the valid\n"
+           "    options are the same as for the 'cache' option\n"
            "  'size' is the disk image size in bytes. Optional suffixes\n"
            "    'k' or 'K' (kilobyte, 1024), 'M' (megabyte, 1024k), 'G' (gigabyte, 1024M),\n"
            "    'T' (terabyte, 1024G), 'P' (petabyte, 1024T) and 'E' (exabyte, 1024P)  are\n"
diff --git a/qemu-img.texi b/qemu-img.texi
index cb68948..4380d56 100644
--- a/qemu-img.texi
+++ b/qemu-img.texi
@@ -73,8 +73,9 @@ specifies the cache mode that should be used with the (destination) file. See
 the documentation of the emulator's @code{-drive cache=...} option for allowed
 values.
 @item -T @var{src_cache}
-in contrast specifies the cache mode that should be used with the source
-file(s).
+specifies the cache mode that should be used with the source file(s). See
+the documentation of the emulator's @code{-drive cache=...} option for allowed
+values.
 @end table
 
 Parameters to snapshot subcommand:
-- 
1.9.3

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

* [Qemu-devel] [PULL 14/26] qemu-img: fix rebase src_cache option documentation
  2014-09-05 16:13 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (12 preceding siblings ...)
  2014-09-05 16:13 ` [Qemu-devel] [PULL 13/26] qemu-img: clarify src_cache option documentation Stefan Hajnoczi
@ 2014-09-05 16:13 ` Stefan Hajnoczi
  2014-09-05 16:13 ` [Qemu-devel] [PULL 15/26] block/archipelago: Use QEMU atomic builtins Stefan Hajnoczi
                   ` (12 subsequent siblings)
  26 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2014-09-05 16:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Stefan Hajnoczi

The src_cache option (-T) specifies the cache mode for backing files.
It applies both the image's old backing file as well as the new backing
file:

  ret = bdrv_open(&bs_old_backing, backing_name, NULL, NULL, src_flags,
                  old_backing_drv, &local_err);
  if (ret) {
      ...
  }
  if (out_baseimg[0]) {
      bs_new_backing = bdrv_new("new_backing", &error_abort);
      ret = bdrv_open(&bs_new_backing, out_baseimg, NULL, NULL, src_flags,
                      new_backing_drv, &local_err);
      if (ret) {
          ...
      }
  }

The documentation only mentions the new backing file but it really
applies to both.

Suggested-by: Jeff Nelson <jenelson@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
---
 qemu-img.texi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/qemu-img.texi b/qemu-img.texi
index 4380d56..cc4668e 100644
--- a/qemu-img.texi
+++ b/qemu-img.texi
@@ -341,7 +341,7 @@ string), then the image is rebased onto no backing file (i.e. it will exist
 independently of any backing file).
 
 @var{cache} specifies the cache mode to be used for @var{filename}, whereas
-@var{src_cache} specifies the cache mode for reading the new backing file.
+@var{src_cache} specifies the cache mode for reading backing files.
 
 There are two different modes in which @code{rebase} can operate:
 @table @option
-- 
1.9.3

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

* [Qemu-devel] [PULL 15/26] block/archipelago: Use QEMU atomic builtins
  2014-09-05 16:13 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (13 preceding siblings ...)
  2014-09-05 16:13 ` [Qemu-devel] [PULL 14/26] qemu-img: fix rebase " Stefan Hajnoczi
@ 2014-09-05 16:13 ` Stefan Hajnoczi
  2014-09-05 16:13 ` [Qemu-devel] [PULL 16/26] rename parse_enum_option to qapi_enum_parse and make it public Stefan Hajnoczi
                   ` (11 subsequent siblings)
  26 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2014-09-05 16:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Chrysostomos Nanakos, Peter Maydell, Stefan Hajnoczi

From: Chrysostomos Nanakos <cnanakos@grnet.gr>

Replace __sync builtins with ones provided by QEMU
for atomic operations.

Special thanks goes to Paolo Bonzini for his refactoring
suggestion in order to use the already existing atomic builtins
interface.

Signed-off-by: Chrysostomos Nanakos <cnanakos@grnet.gr>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 block/archipelago.c | 76 ++++++++++++++++-------------------------------------
 1 file changed, 23 insertions(+), 53 deletions(-)

diff --git a/block/archipelago.c b/block/archipelago.c
index 34f72dc..22a7daa 100644
--- a/block/archipelago.c
+++ b/block/archipelago.c
@@ -57,6 +57,7 @@
 #include "qapi/qmp/qint.h"
 #include "qapi/qmp/qstring.h"
 #include "qapi/qmp/qjson.h"
+#include "qemu/atomic.h"
 
 #include <inttypes.h>
 #include <xseg/xseg.h>
@@ -214,7 +215,7 @@ static void xseg_request_handler(void *state)
 
                 xseg_put_request(s->xseg, req, s->srcport);
 
-                if ((__sync_add_and_fetch(&segreq->ref, -1)) == 0) {
+                if (atomic_fetch_dec(&segreq->ref) == 1) {
                     if (!segreq->failed) {
                         reqdata->aio_cb->ret = segreq->count;
                         archipelago_finish_aiocb(reqdata);
@@ -233,7 +234,7 @@ static void xseg_request_handler(void *state)
                 segreq->count += req->serviced;
                 xseg_put_request(s->xseg, req, s->srcport);
 
-                if ((__sync_add_and_fetch(&segreq->ref, -1)) == 0) {
+                if (atomic_fetch_dec(&segreq->ref) == 1) {
                     if (!segreq->failed) {
                         reqdata->aio_cb->ret = segreq->count;
                         archipelago_finish_aiocb(reqdata);
@@ -824,78 +825,47 @@ static int archipelago_aio_segmented_rw(BDRVArchipelagoState *s,
                                         ArchipelagoAIOCB *aio_cb,
                                         int op)
 {
-    int i, ret, segments_nr, last_segment_size;
+    int ret, segments_nr;
+    size_t pos = 0;
     ArchipelagoSegmentedRequest *segreq;
 
-    segreq = g_new(ArchipelagoSegmentedRequest, 1);
+    segreq = g_new0(ArchipelagoSegmentedRequest, 1);
 
     if (op == ARCHIP_OP_FLUSH) {
         segments_nr = 1;
-        segreq->ref = segments_nr;
-        segreq->total = count;
-        segreq->count = 0;
-        segreq->failed = 0;
-        ret = archipelago_submit_request(s, 0, count, offset, aio_cb,
-                                           segreq, ARCHIP_OP_FLUSH);
-        if (ret < 0) {
-            goto err_exit;
-        }
-        return 0;
+    } else {
+        segments_nr = (int)(count / MAX_REQUEST_SIZE) + \
+                      ((count % MAX_REQUEST_SIZE) ? 1 : 0);
     }
-
-    segments_nr = (int)(count / MAX_REQUEST_SIZE) + \
-                  ((count % MAX_REQUEST_SIZE) ? 1 : 0);
-    last_segment_size = (int)(count % MAX_REQUEST_SIZE);
-
-    segreq->ref = segments_nr;
     segreq->total = count;
-    segreq->count = 0;
-    segreq->failed = 0;
+    atomic_mb_set(&segreq->ref, segments_nr);
 
-    for (i = 0; i < segments_nr - 1; i++) {
-        ret = archipelago_submit_request(s, i * MAX_REQUEST_SIZE,
-                                           MAX_REQUEST_SIZE,
-                                           offset + i * MAX_REQUEST_SIZE,
-                                           aio_cb, segreq, op);
+    while (segments_nr > 1) {
+        ret = archipelago_submit_request(s, pos,
+                                            MAX_REQUEST_SIZE,
+                                            offset + pos,
+                                            aio_cb, segreq, op);
 
         if (ret < 0) {
             goto err_exit;
         }
+        count -= MAX_REQUEST_SIZE;
+        pos += MAX_REQUEST_SIZE;
+        segments_nr--;
     }
-
-    if ((segments_nr > 1) && last_segment_size) {
-        ret = archipelago_submit_request(s, i * MAX_REQUEST_SIZE,
-                                           last_segment_size,
-                                           offset + i * MAX_REQUEST_SIZE,
-                                           aio_cb, segreq, op);
-    } else if ((segments_nr > 1) && !last_segment_size) {
-        ret = archipelago_submit_request(s, i * MAX_REQUEST_SIZE,
-                                           MAX_REQUEST_SIZE,
-                                           offset + i * MAX_REQUEST_SIZE,
-                                           aio_cb, segreq, op);
-    } else if (segments_nr == 1) {
-            ret = archipelago_submit_request(s, 0, count, offset, aio_cb,
-                                               segreq, op);
-    }
+    ret = archipelago_submit_request(s, pos, count, offset + pos,
+                                     aio_cb, segreq, op);
 
     if (ret < 0) {
         goto err_exit;
     }
-
     return 0;
 
 err_exit:
-    __sync_add_and_fetch(&segreq->failed, 1);
-    if (segments_nr == 1) {
-        if (__sync_add_and_fetch(&segreq->ref, -1) == 0) {
-            g_free(segreq);
-        }
-    } else {
-        if ((__sync_add_and_fetch(&segreq->ref, -segments_nr + i)) == 0) {
-            g_free(segreq);
-        }
+    segreq->failed = 1;
+    if (atomic_fetch_sub(&segreq->ref, segments_nr) == segments_nr) {
+        g_free(segreq);
     }
-
     return ret;
 }
 
-- 
1.9.3

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

* [Qemu-devel] [PULL 16/26] rename parse_enum_option to qapi_enum_parse and make it public
  2014-09-05 16:13 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (14 preceding siblings ...)
  2014-09-05 16:13 ` [Qemu-devel] [PULL 15/26] block/archipelago: Use QEMU atomic builtins Stefan Hajnoczi
@ 2014-09-05 16:13 ` Stefan Hajnoczi
  2014-09-05 16:13 ` [Qemu-devel] [PULL 17/26] qemu-nbd: add option to set detect-zeroes mode Stefan Hajnoczi
                   ` (10 subsequent siblings)
  26 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2014-09-05 16:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Peter Lieven, Stefan Hajnoczi, Hu Tao

From: Peter Lieven <pl@kamp.de>

relaxing the license to LGPLv2+ is intentional.

Suggested-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
Signed-off-by: Peter Lieven <pl@kamp.de>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Benoit Canet <benoit.canet@nodalink.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 blockdev.c          | 30 ++++++------------------------
 include/qapi/util.h | 17 +++++++++++++++++
 qapi/Makefile.objs  |  2 +-
 qapi/qapi-util.c    | 34 ++++++++++++++++++++++++++++++++++
 4 files changed, 58 insertions(+), 25 deletions(-)
 create mode 100644 include/qapi/util.h
 create mode 100644 qapi/qapi-util.c

diff --git a/blockdev.c b/blockdev.c
index e37b068..e919566 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -39,6 +39,7 @@
 #include "qapi/qmp/types.h"
 #include "qapi-visit.h"
 #include "qapi/qmp-output-visitor.h"
+#include "qapi/util.h"
 #include "sysemu/sysemu.h"
 #include "block/block_int.h"
 #include "qmp-commands.h"
@@ -274,25 +275,6 @@ static int parse_block_error_action(const char *buf, bool is_read, Error **errp)
     }
 }
 
-static inline int parse_enum_option(const char *lookup[], const char *buf,
-                                    int max, int def, Error **errp)
-{
-    int i;
-
-    if (!buf) {
-        return def;
-    }
-
-    for (i = 0; i < max; i++) {
-        if (!strcmp(buf, lookup[i])) {
-            return i;
-        }
-    }
-
-    error_setg(errp, "invalid parameter value: %s", buf);
-    return def;
-}
-
 static bool check_throttle_config(ThrottleConfig *cfg, Error **errp)
 {
     if (throttle_conflicting(cfg)) {
@@ -456,11 +438,11 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
     }
 
     detect_zeroes =
-        parse_enum_option(BlockdevDetectZeroesOptions_lookup,
-                          qemu_opt_get(opts, "detect-zeroes"),
-                          BLOCKDEV_DETECT_ZEROES_OPTIONS_MAX,
-                          BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF,
-                          &error);
+        qapi_enum_parse(BlockdevDetectZeroesOptions_lookup,
+                        qemu_opt_get(opts, "detect-zeroes"),
+                        BLOCKDEV_DETECT_ZEROES_OPTIONS_MAX,
+                        BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF,
+                        &error);
     if (error) {
         error_propagate(errp, error);
         goto early_err;
diff --git a/include/qapi/util.h b/include/qapi/util.h
new file mode 100644
index 0000000..de9238b
--- /dev/null
+++ b/include/qapi/util.h
@@ -0,0 +1,17 @@
+/*
+ * QAPI util functions
+ *
+ * Copyright Fujitsu, Inc. 2014
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef QAPI_UTIL_H
+#define QAPI_UTIL_H
+
+int qapi_enum_parse(const char *lookup[], const char *buf,
+                    int max, int def, Error **errp);
+
+#endif
diff --git a/qapi/Makefile.objs b/qapi/Makefile.objs
index d14b769..2278970 100644
--- a/qapi/Makefile.objs
+++ b/qapi/Makefile.objs
@@ -1,6 +1,6 @@
 util-obj-y = qapi-visit-core.o qapi-dealloc-visitor.o qmp-input-visitor.o
 util-obj-y += qmp-output-visitor.o qmp-registry.o qmp-dispatch.o
 util-obj-y += string-input-visitor.o string-output-visitor.o
-
 util-obj-y += opts-visitor.o
 util-obj-y += qmp-event.o
+util-obj-y += qapi-util.o
diff --git a/qapi/qapi-util.c b/qapi/qapi-util.c
new file mode 100644
index 0000000..1d8fb96
--- /dev/null
+++ b/qapi/qapi-util.c
@@ -0,0 +1,34 @@
+/*
+ * QAPI util functions
+ *
+ * Authors:
+ *  Hu Tao       <hutao@cn.fujitsu.com>
+ *  Peter Lieven <pl@kamp.de>
+ * 
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#include "qemu-common.h"
+#include "qapi/error.h"
+#include "qapi/util.h"
+
+int qapi_enum_parse(const char *lookup[], const char *buf,
+                    int max, int def, Error **errp)
+{
+    int i;
+
+    if (!buf) {
+        return def;
+    }
+
+    for (i = 0; i < max; i++) {
+        if (!strcmp(buf, lookup[i])) {
+            return i;
+        }
+    }
+
+    error_setg(errp, "invalid parameter value: %s", buf);
+    return def;
+}
-- 
1.9.3

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

* [Qemu-devel] [PULL 17/26] qemu-nbd: add option to set detect-zeroes mode
  2014-09-05 16:13 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (15 preceding siblings ...)
  2014-09-05 16:13 ` [Qemu-devel] [PULL 16/26] rename parse_enum_option to qapi_enum_parse and make it public Stefan Hajnoczi
@ 2014-09-05 16:13 ` Stefan Hajnoczi
  2014-09-05 16:13 ` [Qemu-devel] [PULL 18/26] qemu-nbd: fix indentation and coding style Stefan Hajnoczi
                   ` (9 subsequent siblings)
  26 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2014-09-05 16:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Peter Lieven, Stefan Hajnoczi

From: Peter Lieven <pl@kamp.de>

Signed-off-by: Peter Lieven <pl@kamp.de>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Benoit Canet <benoit.canet@nodalink.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 qemu-nbd.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/qemu-nbd.c b/qemu-nbd.c
index 626e584..6ef8b10 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -18,11 +18,13 @@
 
 #include "qemu-common.h"
 #include "block/block.h"
+#include "block/block_int.h"
 #include "block/nbd.h"
 #include "qemu/main-loop.h"
 #include "qemu/sockets.h"
 #include "qemu/error-report.h"
 #include "block/snapshot.h"
+#include "qapi/util.h"
 
 #include <stdarg.h>
 #include <stdio.h>
@@ -41,6 +43,7 @@
 #define QEMU_NBD_OPT_CACHE   1
 #define QEMU_NBD_OPT_AIO     2
 #define QEMU_NBD_OPT_DISCARD 3
+#define QEMU_NBD_OPT_DETECT_ZEROES 4
 
 static NBDExport *exp;
 static int verbose;
@@ -96,6 +99,8 @@ static void usage(const char *name)
 #ifdef CONFIG_LINUX_AIO
 "      --aio=MODE       set AIO mode (native or threads)\n"
 #endif
+"      --discard=MODE        set discard mode (ignore, unmap)\n"
+"      --detect-zeroes=MODE  set detect-zeroes mode (off, on, discard)\n"
 "\n"
 "Report bugs to <qemu-devel@nongnu.org>\n"
     , name, NBD_DEFAULT_PORT, "DEVICE");
@@ -410,6 +415,7 @@ int main(int argc, char **argv)
         { "aio", 1, NULL, QEMU_NBD_OPT_AIO },
 #endif
         { "discard", 1, NULL, QEMU_NBD_OPT_DISCARD },
+        { "detect-zeroes", 1, NULL, QEMU_NBD_OPT_DETECT_ZEROES },
         { "shared", 1, NULL, 'e' },
         { "format", 1, NULL, 'f' },
         { "persistent", 0, NULL, 't' },
@@ -432,6 +438,7 @@ int main(int argc, char **argv)
     pthread_t client_thread;
     const char *fmt = NULL;
     Error *local_err = NULL;
+    BlockdevDetectZeroesOptions detect_zeroes = BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF;
 
     /* The client thread uses SIGTERM to interrupt the server.  A signal
      * handler ensures that "qemu-nbd -v -c" exits with a nice status code.
@@ -483,6 +490,23 @@ int main(int argc, char **argv)
                 errx(EXIT_FAILURE, "Invalid discard mode `%s'", optarg);
             }
             break;
+        case QEMU_NBD_OPT_DETECT_ZEROES:
+            detect_zeroes =
+                qapi_enum_parse(BlockdevDetectZeroesOptions_lookup,
+                                optarg,
+                                BLOCKDEV_DETECT_ZEROES_OPTIONS_MAX,
+                                BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF,
+                                &local_err);
+            if (local_err) {
+                errx(EXIT_FAILURE, "Failed to parse detect_zeroes mode: %s", 
+                     error_get_pretty(local_err));
+            }
+            if (detect_zeroes == BLOCKDEV_DETECT_ZEROES_OPTIONS_UNMAP &&
+                !(flags & BDRV_O_UNMAP)) {
+                errx(EXIT_FAILURE, "setting detect-zeroes to unmap is not allowed "
+                                   "without setting discard operation to unmap"); 
+            }
+            break;
         case 'b':
             bindto = optarg;
             break;
@@ -686,6 +710,7 @@ int main(int argc, char **argv)
             error_get_pretty(local_err));
     }
 
+    bs->detect_zeroes = detect_zeroes;
     fd_size = bdrv_getlength(bs);
 
     if (partition != -1) {
-- 
1.9.3

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

* [Qemu-devel] [PULL 18/26] qemu-nbd: fix indentation and coding style
  2014-09-05 16:13 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (16 preceding siblings ...)
  2014-09-05 16:13 ` [Qemu-devel] [PULL 17/26] qemu-nbd: add option to set detect-zeroes mode Stefan Hajnoczi
@ 2014-09-05 16:13 ` Stefan Hajnoczi
  2014-09-05 16:13 ` [Qemu-devel] [PULL 19/26] MAINTAINERS: update sheepdog maintainer Stefan Hajnoczi
                   ` (8 subsequent siblings)
  26 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2014-09-05 16:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Peter Lieven, Stefan Hajnoczi

From: Peter Lieven <pl@kamp.de>

Signed-off-by: Peter Lieven <pl@kamp.de>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Benoit Canet <benoit.canet@nodalink.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 qemu-nbd.c | 75 ++++++++++++++++++++++++++++++++------------------------------
 1 file changed, 39 insertions(+), 36 deletions(-)

diff --git a/qemu-nbd.c b/qemu-nbd.c
index 6ef8b10..9bc152e 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -39,10 +39,10 @@
 #include <libgen.h>
 #include <pthread.h>
 
-#define SOCKET_PATH          "/var/lock/qemu-nbd-%s"
-#define QEMU_NBD_OPT_CACHE   1
-#define QEMU_NBD_OPT_AIO     2
-#define QEMU_NBD_OPT_DISCARD 3
+#define SOCKET_PATH                "/var/lock/qemu-nbd-%s"
+#define QEMU_NBD_OPT_CACHE         1
+#define QEMU_NBD_OPT_AIO           2
+#define QEMU_NBD_OPT_DISCARD       3
 #define QEMU_NBD_OPT_DETECT_ZEROES 4
 
 static NBDExport *exp;
@@ -60,44 +60,44 @@ static void usage(const char *name)
 "Usage: %s [OPTIONS] FILE\n"
 "QEMU Disk Network Block Device Server\n"
 "\n"
-"  -h, --help           display this help and exit\n"
-"  -V, --version        output version information and exit\n"
+"  -h, --help                display this help and exit\n"
+"  -V, --version             output version information and exit\n"
 "\n"
 "Connection properties:\n"
-"  -p, --port=PORT      port to listen on (default `%d')\n"
-"  -b, --bind=IFACE     interface to bind to (default `0.0.0.0')\n"
-"  -k, --socket=PATH    path to the unix socket\n"
-"                       (default '"SOCKET_PATH"')\n"
-"  -e, --shared=NUM     device can be shared by NUM clients (default '1')\n"
-"  -t, --persistent     don't exit on the last connection\n"
-"  -v, --verbose        display extra debugging information\n"
+"  -p, --port=PORT           port to listen on (default `%d')\n"
+"  -b, --bind=IFACE          interface to bind to (default `0.0.0.0')\n"
+"  -k, --socket=PATH         path to the unix socket\n"
+"                            (default '"SOCKET_PATH"')\n"
+"  -e, --shared=NUM          device can be shared by NUM clients (default '1')\n"
+"  -t, --persistent          don't exit on the last connection\n"
+"  -v, --verbose             display extra debugging information\n"
 "\n"
 "Exposing part of the image:\n"
-"  -o, --offset=OFFSET  offset into the image\n"
-"  -P, --partition=NUM  only expose partition NUM\n"
+"  -o, --offset=OFFSET       offset into the image\n"
+"  -P, --partition=NUM       only expose partition NUM\n"
 "\n"
 #ifdef __linux__
 "Kernel NBD client support:\n"
-"  -c, --connect=DEV    connect FILE to the local NBD device DEV\n"
-"  -d, --disconnect     disconnect the specified device\n"
+"  -c, --connect=DEV         connect FILE to the local NBD device DEV\n"
+"  -d, --disconnect          disconnect the specified device\n"
 "\n"
 #endif
 "\n"
 "Block device options:\n"
-"  -f, --format=FORMAT  set image format (raw, qcow2, ...)\n"
-"  -r, --read-only      export read-only\n"
-"  -s, --snapshot       use FILE as an external snapshot, create a temporary\n"
-"                       file with backing_file=FILE, redirect the write to\n"
-"                       the temporary one\n"
+"  -f, --format=FORMAT       set image format (raw, qcow2, ...)\n"
+"  -r, --read-only           export read-only\n"
+"  -s, --snapshot            use FILE as an external snapshot, create a temporary\n"
+"                            file with backing_file=FILE, redirect the write to\n"
+"                            the temporary one\n"
 "  -l, --load-snapshot=SNAPSHOT_PARAM\n"
-"                       load an internal snapshot inside FILE and export it\n"
-"                       as an read-only device, SNAPSHOT_PARAM format is\n"
-"                       'snapshot.id=[ID],snapshot.name=[NAME]', or\n"
-"                       '[ID_OR_NAME]'\n"
-"  -n, --nocache        disable host cache\n"
-"      --cache=MODE     set cache mode (none, writeback, ...)\n"
+"                            load an internal snapshot inside FILE and export it\n"
+"                            as an read-only device, SNAPSHOT_PARAM format is\n"
+"                            'snapshot.id=[ID],snapshot.name=[NAME]', or\n"
+"                            '[ID_OR_NAME]'\n"
+"  -n, --nocache             disable host cache\n"
+"      --cache=MODE          set cache mode (none, writeback, ...)\n"
 #ifdef CONFIG_LINUX_AIO
-"      --aio=MODE       set AIO mode (native or threads)\n"
+"      --aio=MODE            set AIO mode (native or threads)\n"
 #endif
 "      --discard=MODE        set discard mode (ignore, unmap)\n"
 "      --detect-zeroes=MODE  set detect-zeroes mode (off, on, discard)\n"
@@ -546,15 +546,18 @@ int main(int argc, char **argv)
             break;
         case 'P':
             partition = strtol(optarg, &end, 0);
-            if (*end)
+            if (*end) {
                 errx(EXIT_FAILURE, "Invalid partition `%s'", optarg);
-            if (partition < 1 || partition > 8)
+            }
+            if (partition < 1 || partition > 8) {
                 errx(EXIT_FAILURE, "Invalid partition %d", partition);
+            }
             break;
         case 'k':
             sockpath = optarg;
-            if (sockpath[0] != '/')
+            if (sockpath[0] != '/') {
                 errx(EXIT_FAILURE, "socket path must be absolute\n");
+            }
             break;
         case 'd':
             disconnect = true;
@@ -574,9 +577,9 @@ int main(int argc, char **argv)
         case 'f':
             fmt = optarg;
             break;
-	case 't':
-	    persistent = 1;
-	    break;
+        case 't':
+            persistent = 1;
+            break;
         case 'v':
             verbose = 1;
             break;
@@ -611,7 +614,7 @@ int main(int argc, char **argv)
 
         printf("%s disconnected\n", argv[optind]);
 
-	return 0;
+        return 0;
     }
 
     if (device && !verbose) {
-- 
1.9.3

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

* [Qemu-devel] [PULL 19/26] MAINTAINERS: update sheepdog maintainer
  2014-09-05 16:13 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (17 preceding siblings ...)
  2014-09-05 16:13 ` [Qemu-devel] [PULL 18/26] qemu-nbd: fix indentation and coding style Stefan Hajnoczi
@ 2014-09-05 16:13 ` Stefan Hajnoczi
  2014-09-05 16:13 ` [Qemu-devel] [PULL 20/26] libqos: add a simple first-fit memory allocator Stefan Hajnoczi
                   ` (7 subsequent siblings)
  26 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2014-09-05 16:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: MORITA Kazutaka, Peter Maydell, Stefan Hajnoczi

From: MORITA Kazutaka <morita.kazutaka@gmail.com>

Hitoshi takes over sheepdog maintenance from me.

Signed-off-by: MORITA Kazutaka <morita.kazutaka@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 MAINTAINERS | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 142f68a..42a668b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -974,7 +974,7 @@ S: Supported
 F: block/rbd.c
 
 Sheepdog
-M: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
+M: Hitoshi Mitake <mitake.hitoshi@lab.ntt.co.jp>
 M: Liu Yuan <namei.unix@gmail.com>
 L: sheepdog@lists.wpkg.org
 S: Supported
-- 
1.9.3

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

* [Qemu-devel] [PULL 20/26] libqos: add a simple first-fit memory allocator
  2014-09-05 16:13 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (18 preceding siblings ...)
  2014-09-05 16:13 ` [Qemu-devel] [PULL 19/26] MAINTAINERS: update sheepdog maintainer Stefan Hajnoczi
@ 2014-09-05 16:13 ` Stefan Hajnoczi
  2014-09-05 16:13 ` [Qemu-devel] [PULL 21/26] qtest/ide: Uninitialize PC allocator Stefan Hajnoczi
                   ` (6 subsequent siblings)
  26 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2014-09-05 16:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, John Snow, Stefan Hajnoczi

From: John Snow <jsnow@redhat.com>

Implement a simple first-fit memory allocator that
attempts to keep track of leased blocks of memory
in order to be able to re-use blocks.

Additionally, allow the user to specify when
initializing the device that upon cleanup,
we would like to assert that there are no
blocks in use. This may be useful for identifying
problems in qtests that use more complicated
set-up and tear-down routines.

This functionality is used in my upcoming ahci-test v2
patch set, but I didn't see fit to enable it for any
existing tests, which will continue to operate the
same as they have prior.

Signed-off-by: John Snow <jsnow@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 tests/libqos/malloc-pc.c | 280 +++++++++++++++++++++++++++++++++++++++++++++--
 tests/libqos/malloc-pc.h |   9 ++
 2 files changed, 279 insertions(+), 10 deletions(-)

diff --git a/tests/libqos/malloc-pc.c b/tests/libqos/malloc-pc.c
index be1d97f..f4218c6 100644
--- a/tests/libqos/malloc-pc.c
+++ b/tests/libqos/malloc-pc.c
@@ -17,45 +17,294 @@
 #include "hw/nvram/fw_cfg.h"
 
 #include "qemu-common.h"
+#include "qemu/queue.h"
 #include <glib.h>
 
 #define PAGE_SIZE (4096)
 
+#define MLIST_ENTNAME entries
+typedef QTAILQ_HEAD(MemList, MemBlock) MemList;
+typedef struct MemBlock {
+    QTAILQ_ENTRY(MemBlock) MLIST_ENTNAME;
+    uint64_t size;
+    uint64_t addr;
+} MemBlock;
+
 typedef struct PCAlloc
 {
     QGuestAllocator alloc;
-
+    PCAllocOpts opts;
     uint64_t start;
     uint64_t end;
+
+    MemList used;
+    MemList free;
 } PCAlloc;
 
-static uint64_t pc_alloc(QGuestAllocator *allocator, size_t size)
+static MemBlock *mlist_new(uint64_t addr, uint64_t size)
 {
-    PCAlloc *s = container_of(allocator, PCAlloc, alloc);
-    uint64_t addr;
+    MemBlock *block;
+
+    if (!size) {
+        return NULL;
+    }
+    block = g_malloc0(sizeof(MemBlock));
 
+    block->addr = addr;
+    block->size = size;
 
-    size += (PAGE_SIZE - 1);
-    size &= -PAGE_SIZE;
+    return block;
+}
+
+static void mlist_delete(MemList *list, MemBlock *node)
+{
+    g_assert(list && node);
+    QTAILQ_REMOVE(list, node, MLIST_ENTNAME);
+    g_free(node);
+}
+
+static MemBlock *mlist_find_key(MemList *head, uint64_t addr)
+{
+    MemBlock *node;
+    QTAILQ_FOREACH(node, head, MLIST_ENTNAME) {
+        if (node->addr == addr) {
+            return node;
+        }
+    }
+    return NULL;
+}
+
+static MemBlock *mlist_find_space(MemList *head, uint64_t size)
+{
+    MemBlock *node;
+
+    QTAILQ_FOREACH(node, head, MLIST_ENTNAME) {
+        if (node->size >= size) {
+            return node;
+        }
+    }
+    return NULL;
+}
+
+static MemBlock *mlist_sort_insert(MemList *head, MemBlock *insr)
+{
+    MemBlock *node;
+    g_assert(head && insr);
+
+    QTAILQ_FOREACH(node, head, MLIST_ENTNAME) {
+        if (insr->addr < node->addr) {
+            QTAILQ_INSERT_BEFORE(node, insr, MLIST_ENTNAME);
+            return insr;
+        }
+    }
+
+    QTAILQ_INSERT_TAIL(head, insr, MLIST_ENTNAME);
+    return insr;
+}
+
+static inline uint64_t mlist_boundary(MemBlock *node)
+{
+    return node->size + node->addr;
+}
+
+static MemBlock *mlist_join(MemList *head, MemBlock *left, MemBlock *right)
+{
+    g_assert(head && left && right);
+
+    left->size += right->size;
+    mlist_delete(head, right);
+    return left;
+}
+
+static void mlist_coalesce(MemList *head, MemBlock *node)
+{
+    g_assert(node);
+    MemBlock *left;
+    MemBlock *right;
+    char merge;
+
+    do {
+        merge = 0;
+        left = QTAILQ_PREV(node, MemList, MLIST_ENTNAME);
+        right = QTAILQ_NEXT(node, MLIST_ENTNAME);
+
+        /* clowns to the left of me */
+        if (left && mlist_boundary(left) == node->addr) {
+            node = mlist_join(head, left, node);
+            merge = 1;
+        }
+
+        /* jokers to the right */
+        if (right && mlist_boundary(node) == right->addr) {
+            node = mlist_join(head, node, right);
+            merge = 1;
+        }
+
+    } while (merge);
+}
+
+static uint64_t pc_mlist_fulfill(PCAlloc *s, MemBlock *freenode, uint64_t size)
+{
+    uint64_t addr;
+    MemBlock *usednode;
 
-    g_assert_cmpint((s->start + size), <=, s->end);
+    g_assert(freenode);
+    g_assert_cmpint(freenode->size, >=, size);
 
-    addr = s->start;
-    s->start += size;
+    addr = freenode->addr;
+    if (freenode->size == size) {
+        /* re-use this freenode as our used node */
+        QTAILQ_REMOVE(&s->free, freenode, MLIST_ENTNAME);
+        usednode = freenode;
+    } else {
+        /* adjust the free node and create a new used node */
+        freenode->addr += size;
+        freenode->size -= size;
+        usednode = mlist_new(addr, size);
+    }
 
+    mlist_sort_insert(&s->used, usednode);
     return addr;
 }
 
+/* To assert the correctness of the list.
+ * Used only if PC_ALLOC_PARANOID is set. */
+static void pc_mlist_check(PCAlloc *s)
+{
+    MemBlock *node;
+    uint64_t addr = s->start > 0 ? s->start - 1 : 0;
+    uint64_t next = s->start;
+
+    QTAILQ_FOREACH(node, &s->free, MLIST_ENTNAME) {
+        g_assert_cmpint(node->addr, >, addr);
+        g_assert_cmpint(node->addr, >=, next);
+        addr = node->addr;
+        next = node->addr + node->size;
+    }
+
+    addr = s->start > 0 ? s->start - 1 : 0;
+    next = s->start;
+    QTAILQ_FOREACH(node, &s->used, MLIST_ENTNAME) {
+        g_assert_cmpint(node->addr, >, addr);
+        g_assert_cmpint(node->addr, >=, next);
+        addr = node->addr;
+        next = node->addr + node->size;
+    }
+}
+
+static uint64_t pc_mlist_alloc(PCAlloc *s, uint64_t size)
+{
+    MemBlock *node;
+
+    node = mlist_find_space(&s->free, size);
+    if (!node) {
+        fprintf(stderr, "Out of guest memory.\n");
+        g_assert_not_reached();
+    }
+    return pc_mlist_fulfill(s, node, size);
+}
+
+static void pc_mlist_free(PCAlloc *s, uint64_t addr)
+{
+    MemBlock *node;
+
+    if (addr == 0) {
+        return;
+    }
+
+    node = mlist_find_key(&s->used, addr);
+    if (!node) {
+        fprintf(stderr, "Error: no record found for an allocation at "
+                "0x%016" PRIx64 ".\n",
+                addr);
+        g_assert_not_reached();
+    }
+
+    /* Rip it out of the used list and re-insert back into the free list. */
+    QTAILQ_REMOVE(&s->used, node, MLIST_ENTNAME);
+    mlist_sort_insert(&s->free, node);
+    mlist_coalesce(&s->free, node);
+}
+
+static uint64_t pc_alloc(QGuestAllocator *allocator, size_t size)
+{
+    PCAlloc *s = container_of(allocator, PCAlloc, alloc);
+    uint64_t rsize = size;
+    uint64_t naddr;
+
+    rsize += (PAGE_SIZE - 1);
+    rsize &= -PAGE_SIZE;
+    g_assert_cmpint((s->start + rsize), <=, s->end);
+    g_assert_cmpint(rsize, >=, size);
+
+    naddr = pc_mlist_alloc(s, rsize);
+    if (s->opts & PC_ALLOC_PARANOID) {
+        pc_mlist_check(s);
+    }
+
+    return naddr;
+}
+
 static void pc_free(QGuestAllocator *allocator, uint64_t addr)
 {
+    PCAlloc *s = container_of(allocator, PCAlloc, alloc);
+
+    pc_mlist_free(s, addr);
+    if (s->opts & PC_ALLOC_PARANOID) {
+        pc_mlist_check(s);
+    }
+}
+
+/*
+ * Mostly for valgrind happiness, but it does offer
+ * a chokepoint for debugging guest memory leaks, too.
+ */
+void pc_alloc_uninit(QGuestAllocator *allocator)
+{
+    PCAlloc *s = container_of(allocator, PCAlloc, alloc);
+    MemBlock *node;
+    MemBlock *tmp;
+    PCAllocOpts mask;
+
+    /* Check for guest leaks, and destroy the list. */
+    QTAILQ_FOREACH_SAFE(node, &s->used, MLIST_ENTNAME, tmp) {
+        if (s->opts & (PC_ALLOC_LEAK_WARN | PC_ALLOC_LEAK_ASSERT)) {
+            fprintf(stderr, "guest malloc leak @ 0x%016" PRIx64 "; "
+                    "size 0x%016" PRIx64 ".\n",
+                    node->addr, node->size);
+        }
+        if (s->opts & (PC_ALLOC_LEAK_ASSERT)) {
+            g_assert_not_reached();
+        }
+        g_free(node);
+    }
+
+    /* If we have previously asserted that there are no leaks, then there
+     * should be only one node here with a specific address and size. */
+    mask = PC_ALLOC_LEAK_ASSERT | PC_ALLOC_PARANOID;
+    QTAILQ_FOREACH_SAFE(node, &s->free, MLIST_ENTNAME, tmp) {
+        if ((s->opts & mask) == mask) {
+            if ((node->addr != s->start) ||
+                (node->size != s->end - s->start)) {
+                fprintf(stderr, "Free list is corrupted.\n");
+                g_assert_not_reached();
+            }
+        }
+
+        g_free(node);
+    }
+
+    g_free(s);
 }
 
-QGuestAllocator *pc_alloc_init(void)
+QGuestAllocator *pc_alloc_init_flags(PCAllocOpts flags)
 {
     PCAlloc *s = g_malloc0(sizeof(*s));
     uint64_t ram_size;
     QFWCFG *fw_cfg = pc_fw_cfg_init();
+    MemBlock *node;
 
+    s->opts = flags;
     s->alloc.alloc = pc_alloc;
     s->alloc.free = pc_free;
 
@@ -70,5 +319,16 @@ QGuestAllocator *pc_alloc_init(void)
     /* clean-up */
     g_free(fw_cfg);
 
+    QTAILQ_INIT(&s->used);
+    QTAILQ_INIT(&s->free);
+
+    node = mlist_new(s->start, s->end - s->start);
+    QTAILQ_INSERT_HEAD(&s->free, node, MLIST_ENTNAME);
+
     return &s->alloc;
 }
+
+inline QGuestAllocator *pc_alloc_init(void)
+{
+    return pc_alloc_init_flags(PC_ALLOC_NO_FLAGS);
+}
diff --git a/tests/libqos/malloc-pc.h b/tests/libqos/malloc-pc.h
index ff964ab..9f525e3 100644
--- a/tests/libqos/malloc-pc.h
+++ b/tests/libqos/malloc-pc.h
@@ -15,6 +15,15 @@
 
 #include "libqos/malloc.h"
 
+typedef enum {
+    PC_ALLOC_NO_FLAGS    = 0x00,
+    PC_ALLOC_LEAK_WARN   = 0x01,
+    PC_ALLOC_LEAK_ASSERT = 0x02,
+    PC_ALLOC_PARANOID    = 0x04
+} PCAllocOpts;
+
 QGuestAllocator *pc_alloc_init(void);
+QGuestAllocator *pc_alloc_init_flags(PCAllocOpts flags);
+void             pc_alloc_uninit(QGuestAllocator *allocator);
 
 #endif
-- 
1.9.3

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

* [Qemu-devel] [PULL 21/26] qtest/ide: Uninitialize PC allocator
  2014-09-05 16:13 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (19 preceding siblings ...)
  2014-09-05 16:13 ` [Qemu-devel] [PULL 20/26] libqos: add a simple first-fit memory allocator Stefan Hajnoczi
@ 2014-09-05 16:13 ` Stefan Hajnoczi
  2014-09-05 16:13 ` [Qemu-devel] [PULL 22/26] ide: Add wwn support to IDE-ATAPI drive Stefan Hajnoczi
                   ` (5 subsequent siblings)
  26 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2014-09-05 16:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, John Snow, Stefan Hajnoczi

From: John Snow <jsnow@redhat.com>

Use the new call to pc_alloc_uninit
as a test for the new pathways.

The leak checking / assert pathways are
not enabled in this patch, leaving this
as an option to future test writers.

Signed-off-by: John Snow <jsnow@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 tests/ide-test.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/tests/ide-test.c b/tests/ide-test.c
index ffce6ed..b7a97e9 100644
--- a/tests/ide-test.c
+++ b/tests/ide-test.c
@@ -126,6 +126,8 @@ static void ide_test_start(const char *cmdline_fmt, ...)
 
 static void ide_test_quit(void)
 {
+    pc_alloc_uninit(guest_malloc);
+    guest_malloc = NULL;
     qtest_end();
 }
 
-- 
1.9.3

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

* [Qemu-devel] [PULL 22/26] ide: Add wwn support to IDE-ATAPI drive
  2014-09-05 16:13 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (20 preceding siblings ...)
  2014-09-05 16:13 ` [Qemu-devel] [PULL 21/26] qtest/ide: Uninitialize PC allocator Stefan Hajnoczi
@ 2014-09-05 16:13 ` Stefan Hajnoczi
  2014-09-05 16:13 ` [Qemu-devel] [PULL 23/26] vmdk: fix vmdk_parse_extents() extent_file leaks Stefan Hajnoczi
                   ` (4 subsequent siblings)
  26 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2014-09-05 16:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, John Snow, Stefan Hajnoczi

From: John Snow <jsnow@redhat.com>

Although it is possible to specify the wwn
property for cdrom devices on the command line,
the underlying driver fails to relay this information
to the guest operating system via IDENTIFY.

This is a simple patch to correct that.

See ATA8-ACS, Table 22 parts 5, 6, and 9.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 hw/ide/core.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/hw/ide/core.c b/hw/ide/core.c
index b48127f..de0e5e9 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -230,9 +230,23 @@ static void ide_atapi_identify(IDEState *s)
     }
 
     put_le16(p + 80, 0x1e); /* support up to ATA/ATAPI-4 */
+    if (s->wwn) {
+        put_le16(p + 84, (1 << 8)); /* supports WWN for words 108-111 */
+        put_le16(p + 87, (1 << 8)); /* WWN enabled */
+    }
+
 #ifdef USE_DMA_CDROM
     put_le16(p + 88, 0x3f | (1 << 13)); /* udma5 set and supported */
 #endif
+
+    if (s->wwn) {
+        /* LE 16-bit words 111-108 contain 64-bit World Wide Name */
+        put_le16(p + 108, s->wwn >> 48);
+        put_le16(p + 109, s->wwn >> 32);
+        put_le16(p + 110, s->wwn >> 16);
+        put_le16(p + 111, s->wwn);
+    }
+
     memcpy(s->identify_data, p, sizeof(s->identify_data));
     s->identify_set = 1;
 }
-- 
1.9.3

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

* [Qemu-devel] [PULL 23/26] vmdk: fix vmdk_parse_extents() extent_file leaks
  2014-09-05 16:13 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (21 preceding siblings ...)
  2014-09-05 16:13 ` [Qemu-devel] [PULL 22/26] ide: Add wwn support to IDE-ATAPI drive Stefan Hajnoczi
@ 2014-09-05 16:13 ` Stefan Hajnoczi
  2014-09-05 16:13 ` [Qemu-devel] [PULL 24/26] vmdk: fix buf leak in vmdk_parse_extents() Stefan Hajnoczi
                   ` (3 subsequent siblings)
  26 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2014-09-05 16:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Stefan Hajnoczi

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
---
 block/vmdk.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/block/vmdk.c b/block/vmdk.c
index 07cb62c..9bf28f3 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -834,6 +834,7 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
             ret = vmdk_add_extent(bs, extent_file, true, sectors,
                             0, 0, 0, 0, 0, &extent, errp);
             if (ret < 0) {
+                bdrv_unref(extent_file);
                 return ret;
             }
             extent->flat_start_offset = flat_offset << 9;
@@ -853,6 +854,7 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
             extent = &s->extents[s->num_extents - 1];
         } else {
             error_setg(errp, "Unsupported extent type '%s'", type);
+            bdrv_unref(extent_file);
             return -ENOTSUP;
         }
         extent->type = g_strdup(type);
-- 
1.9.3

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

* [Qemu-devel] [PULL 24/26] vmdk: fix buf leak in vmdk_parse_extents()
  2014-09-05 16:13 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (22 preceding siblings ...)
  2014-09-05 16:13 ` [Qemu-devel] [PULL 23/26] vmdk: fix vmdk_parse_extents() extent_file leaks Stefan Hajnoczi
@ 2014-09-05 16:13 ` Stefan Hajnoczi
  2014-09-05 16:13 ` [Qemu-devel] [PULL 25/26] IDE: Fill the IDENTIFY request consistently Stefan Hajnoczi
                   ` (2 subsequent siblings)
  26 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2014-09-05 16:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Stefan Hajnoczi

vmdk_open_sparse() does not take ownership of buf so the caller always
needs to free it.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
---
 block/vmdk.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index 9bf28f3..a1cb911 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -846,8 +846,8 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
             } else {
                 ret = vmdk_open_sparse(bs, extent_file, bs->open_flags, buf, errp);
             }
+            g_free(buf);
             if (ret) {
-                g_free(buf);
                 bdrv_unref(extent_file);
                 return ret;
             }
-- 
1.9.3

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

* [Qemu-devel] [PULL 25/26] IDE: Fill the IDENTIFY request consistently
  2014-09-05 16:13 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (23 preceding siblings ...)
  2014-09-05 16:13 ` [Qemu-devel] [PULL 24/26] vmdk: fix buf leak in vmdk_parse_extents() Stefan Hajnoczi
@ 2014-09-05 16:13 ` Stefan Hajnoczi
  2014-09-05 16:13 ` [Qemu-devel] [PULL 26/26] ide: Add resize callback to ide/core Stefan Hajnoczi
  2014-09-05 16:32 ` [Qemu-devel] [PULL 00/26] Block patches Peter Maydell
  26 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2014-09-05 16:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, John Snow, Stefan Hajnoczi

From: John Snow <jsnow@redhat.com>

IDE-HD, IDE-ATAPI and IDE-CFATA all fill the
identify buffer in slightly different ways,
this is a relatively minor patch to make them
uniform, to emphasize that:

(1) We build the s->identify_data cache first, then
(2) We copy it to s->io_buffer to fulfill the request.

Signed-off-by: John Snow <jsnow@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 hw/ide/core.c | 28 +++++++++++++++-------------
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/hw/ide/core.c b/hw/ide/core.c
index de0e5e9..e0232d4 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -81,13 +81,12 @@ static void ide_identify(IDEState *s)
     unsigned int oldsize;
     IDEDevice *dev = s->unit ? s->bus->slave : s->bus->master;
 
+    p = (uint16_t *)s->identify_data;
     if (s->identify_set) {
-	memcpy(s->io_buffer, s->identify_data, sizeof(s->identify_data));
-	return;
+        goto fill_buffer;
     }
+    memset(p, 0, sizeof(s->identify_data));
 
-    memset(s->io_buffer, 0, 512);
-    p = (uint16_t *)s->io_buffer;
     put_le16(p + 0, 0x0040);
     put_le16(p + 1, s->cylinders);
     put_le16(p + 3, s->heads);
@@ -180,21 +179,22 @@ static void ide_identify(IDEState *s)
         put_le16(p + 169, 1); /* TRIM support */
     }
 
-    memcpy(s->identify_data, p, sizeof(s->identify_data));
     s->identify_set = 1;
+
+fill_buffer:
+    memcpy(s->io_buffer, p, sizeof(s->identify_data));
 }
 
 static void ide_atapi_identify(IDEState *s)
 {
     uint16_t *p;
 
+    p = (uint16_t *)s->identify_data;
     if (s->identify_set) {
-	memcpy(s->io_buffer, s->identify_data, sizeof(s->identify_data));
-	return;
+        goto fill_buffer;
     }
+    memset(p, 0, sizeof(s->identify_data));
 
-    memset(s->io_buffer, 0, 512);
-    p = (uint16_t *)s->io_buffer;
     /* Removable CDROM, 50us response, 12 byte packets */
     put_le16(p + 0, (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0));
     padstr((char *)(p + 10), s->drive_serial_str, 20); /* serial number */
@@ -247,8 +247,10 @@ static void ide_atapi_identify(IDEState *s)
         put_le16(p + 111, s->wwn);
     }
 
-    memcpy(s->identify_data, p, sizeof(s->identify_data));
     s->identify_set = 1;
+
+fill_buffer:
+    memcpy(s->io_buffer, p, sizeof(s->identify_data));
 }
 
 static void ide_cfata_identify(IDEState *s)
@@ -256,10 +258,10 @@ static void ide_cfata_identify(IDEState *s)
     uint16_t *p;
     uint32_t cur_sec;
 
-    p = (uint16_t *) s->identify_data;
-    if (s->identify_set)
+    p = (uint16_t *)s->identify_data;
+    if (s->identify_set) {
         goto fill_buffer;
-
+    }
     memset(p, 0, sizeof(s->identify_data));
 
     cur_sec = s->cylinders * s->heads * s->sectors;
-- 
1.9.3

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

* [Qemu-devel] [PULL 26/26] ide: Add resize callback to ide/core
  2014-09-05 16:13 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (24 preceding siblings ...)
  2014-09-05 16:13 ` [Qemu-devel] [PULL 25/26] IDE: Fill the IDENTIFY request consistently Stefan Hajnoczi
@ 2014-09-05 16:13 ` Stefan Hajnoczi
  2014-09-05 16:32 ` [Qemu-devel] [PULL 00/26] Block patches Peter Maydell
  26 siblings, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2014-09-05 16:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, John Snow, Stefan Hajnoczi

From: John Snow <jsnow@redhat.com>

Currently, if the block device backing the IDE drive is resized,
the information about the device as cached inside of the IDEState
structure is not updated, thus when a guest OS re-queries the drive,
it is unable to see the expanded size.

This patch adds a resize callback that updates the IDENTIFY data
buffer in order to correct this.

Lastly, a Linux guest as-is cannot resize a libata drive while in-use,
but it can see the expanded size as part of a bus rescan event.
This patch also allows guests such as Linux to see the new drive size
after a soft reboot event, without having to exit the QEMU process.

Signed-off-by: John Snow <jsnow@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 hw/ide/core.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 59 insertions(+), 10 deletions(-)

diff --git a/hw/ide/core.c b/hw/ide/core.c
index e0232d4..191f893 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -75,6 +75,17 @@ static void put_le16(uint16_t *p, unsigned int v)
     *p = cpu_to_le16(v);
 }
 
+static void ide_identify_size(IDEState *s)
+{
+    uint16_t *p = (uint16_t *)s->identify_data;
+    put_le16(p + 60, s->nb_sectors);
+    put_le16(p + 61, s->nb_sectors >> 16);
+    put_le16(p + 100, s->nb_sectors);
+    put_le16(p + 101, s->nb_sectors >> 16);
+    put_le16(p + 102, s->nb_sectors >> 32);
+    put_le16(p + 103, s->nb_sectors >> 48);
+}
+
 static void ide_identify(IDEState *s)
 {
     uint16_t *p;
@@ -115,8 +126,8 @@ static void ide_identify(IDEState *s)
     put_le16(p + 58, oldsize >> 16);
     if (s->mult_sectors)
         put_le16(p + 59, 0x100 | s->mult_sectors);
-    put_le16(p + 60, s->nb_sectors);
-    put_le16(p + 61, s->nb_sectors >> 16);
+    /* *(p + 60) := nb_sectors       -- see ide_identify_size */
+    /* *(p + 61) := nb_sectors >> 16 -- see ide_identify_size */
     put_le16(p + 62, 0x07); /* single word dma0-2 supported */
     put_le16(p + 63, 0x07); /* mdma0-2 supported */
     put_le16(p + 64, 0x03); /* pio3-4 supported */
@@ -161,10 +172,10 @@ static void ide_identify(IDEState *s)
     }
     put_le16(p + 88, 0x3f | (1 << 13)); /* udma5 set and supported */
     put_le16(p + 93, 1 | (1 << 14) | 0x2000);
-    put_le16(p + 100, s->nb_sectors);
-    put_le16(p + 101, s->nb_sectors >> 16);
-    put_le16(p + 102, s->nb_sectors >> 32);
-    put_le16(p + 103, s->nb_sectors >> 48);
+    /* *(p + 100) := nb_sectors       -- see ide_identify_size */
+    /* *(p + 101) := nb_sectors >> 16 -- see ide_identify_size */
+    /* *(p + 102) := nb_sectors >> 32 -- see ide_identify_size */
+    /* *(p + 103) := nb_sectors >> 48 -- see ide_identify_size */
 
     if (dev && dev->conf.physical_block_size)
         put_le16(p + 106, 0x6000 | get_physical_block_exp(&dev->conf));
@@ -179,6 +190,7 @@ static void ide_identify(IDEState *s)
         put_le16(p + 169, 1); /* TRIM support */
     }
 
+    ide_identify_size(s);
     s->identify_set = 1;
 
 fill_buffer:
@@ -253,6 +265,15 @@ fill_buffer:
     memcpy(s->io_buffer, p, sizeof(s->identify_data));
 }
 
+static void ide_cfata_identify_size(IDEState *s)
+{
+    uint16_t *p = (uint16_t *)s->identify_data;
+    put_le16(p + 7, s->nb_sectors >> 16);  /* Sectors per card */
+    put_le16(p + 8, s->nb_sectors);        /* Sectors per card */
+    put_le16(p + 60, s->nb_sectors);       /* Total LBA sectors */
+    put_le16(p + 61, s->nb_sectors >> 16); /* Total LBA sectors */
+}
+
 static void ide_cfata_identify(IDEState *s)
 {
     uint16_t *p;
@@ -270,8 +291,8 @@ static void ide_cfata_identify(IDEState *s)
     put_le16(p + 1, s->cylinders);		/* Default cylinders */
     put_le16(p + 3, s->heads);			/* Default heads */
     put_le16(p + 6, s->sectors);		/* Default sectors per track */
-    put_le16(p + 7, s->nb_sectors >> 16);	/* Sectors per card */
-    put_le16(p + 8, s->nb_sectors);		/* Sectors per card */
+    /* *(p + 7) := nb_sectors >> 16 -- see ide_cfata_identify_size */
+    /* *(p + 8) := nb_sectors       -- see ide_cfata_identify_size */
     padstr((char *)(p + 10), s->drive_serial_str, 20); /* serial number */
     put_le16(p + 22, 0x0004);			/* ECC bytes */
     padstr((char *) (p + 23), s->version, 8);	/* Firmware Revision */
@@ -292,8 +313,8 @@ static void ide_cfata_identify(IDEState *s)
     put_le16(p + 58, cur_sec >> 16);		/* Current capacity */
     if (s->mult_sectors)			/* Multiple sector setting */
         put_le16(p + 59, 0x100 | s->mult_sectors);
-    put_le16(p + 60, s->nb_sectors);		/* Total LBA sectors */
-    put_le16(p + 61, s->nb_sectors >> 16);	/* Total LBA sectors */
+    /* *(p + 60) := nb_sectors       -- see ide_cfata_identify_size */
+    /* *(p + 61) := nb_sectors >> 16 -- see ide_cfata_identify_size */
     put_le16(p + 63, 0x0203);			/* Multiword DMA capability */
     put_le16(p + 64, 0x0001);			/* Flow Control PIO support */
     put_le16(p + 65, 0x0096);			/* Min. Multiword DMA cycle */
@@ -313,6 +334,7 @@ static void ide_cfata_identify(IDEState *s)
     put_le16(p + 160, 0x8100);			/* Power requirement */
     put_le16(p + 161, 0x8001);			/* CF command set */
 
+    ide_cfata_identify_size(s);
     s->identify_set = 1;
 
 fill_buffer:
@@ -2131,6 +2153,28 @@ static bool ide_cd_is_medium_locked(void *opaque)
     return ((IDEState *)opaque)->tray_locked;
 }
 
+static void ide_resize_cb(void *opaque)
+{
+    IDEState *s = opaque;
+    uint64_t nb_sectors;
+
+    if (!s->identify_set) {
+        return;
+    }
+
+    bdrv_get_geometry(s->bs, &nb_sectors);
+    s->nb_sectors = nb_sectors;
+
+    /* Update the identify data buffer. */
+    if (s->drive_kind == IDE_CFATA) {
+        ide_cfata_identify_size(s);
+    } else {
+        /* IDE_CD uses a different set of callbacks entirely. */
+        assert(s->drive_kind != IDE_CD);
+        ide_identify_size(s);
+    }
+}
+
 static const BlockDevOps ide_cd_block_ops = {
     .change_media_cb = ide_cd_change_cb,
     .eject_request_cb = ide_cd_eject_request_cb,
@@ -2138,6 +2182,10 @@ static const BlockDevOps ide_cd_block_ops = {
     .is_medium_locked = ide_cd_is_medium_locked,
 };
 
+static const BlockDevOps ide_hd_block_ops = {
+    .resize_cb = ide_resize_cb,
+};
+
 int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
                    const char *version, const char *serial, const char *model,
                    uint64_t wwn,
@@ -2174,6 +2222,7 @@ int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
             error_report("Can't use a read-only drive");
             return -1;
         }
+        bdrv_set_dev_ops(bs, &ide_hd_block_ops, s);
     }
     if (serial) {
         pstrcpy(s->drive_serial_str, sizeof(s->drive_serial_str), serial);
-- 
1.9.3

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

* Re: [Qemu-devel] [PULL 00/26] Block patches
  2014-09-05 16:13 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
                   ` (25 preceding siblings ...)
  2014-09-05 16:13 ` [Qemu-devel] [PULL 26/26] ide: Add resize callback to ide/core Stefan Hajnoczi
@ 2014-09-05 16:32 ` Peter Maydell
  26 siblings, 0 replies; 42+ messages in thread
From: Peter Maydell @ 2014-09-05 16:32 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: QEMU Developers

On 5 September 2014 17:13, Stefan Hajnoczi <stefanha@redhat.com> wrote:
> The following changes since commit 30eaca3acdf17d7bcbd1213eb149c02037edfb0b:
>
>   Merge remote-tracking branch 'remotes/spice/tags/pull-spice-20140902-1' into staging (2014-09-02 10:26:10 +0100)
>
> are available in the git repository at:
>
>
>   git://github.com/stefanha/qemu.git tags/block-pull-request
>
> for you to fetch changes up to 804b985da5f781a2ff0a723c1aae520b9ea95f27:
>
>   ide: Add resize callback to ide/core (2014-09-05 10:38:56 +0100)
>
> ----------------------------------------------------------------
> Block pull request

Hi. I'm afraid this doesn't build on win32:

/home/petmay01/linaro/qemu-for-merges/hw/virtio/dataplane/vring.c: In
function ‘get_desc’:
/home/petmay01/linaro/qemu-for-merges/hw/virtio/dataplane/vring.c:184:
error: ‘ENOBUFS’ undeclared (first use in this function)
/home/petmay01/linaro/qemu-for-merges/hw/virtio/dataplane/vring.c:184:
error: (Each undeclared identifier is reported only once
/home/petmay01/linaro/qemu-for-merges/hw/virtio/dataplane/vring.c:184:
error: for each function it appears in.)

thanks
-- PMM

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

* [Qemu-devel] [PULL 00/26] Block patches
@ 2015-01-09 10:16 Stefan Hajnoczi
  2015-01-10 19:05 ` Peter Maydell
  0 siblings, 1 reply; 42+ messages in thread
From: Stefan Hajnoczi @ 2015-01-09 10:16 UTC (permalink / raw)
  To: qemu-devel; +Cc: Peter Maydell, Stefan Hajnoczi

This pull request depends on the previous block pull request which has not been
merged yet.  It was sent on Monday, 5th of January (Message-id:
<1420458696-1885-1-git-send-email-stefanha@redhat.com>).

The following changes since commit 3bd54e576f40f1d5bf45b4828c7316efd76a4db6:

  migration/block: fix pending() return value (2015-01-05 11:34:52 +0000)

are available in the git repository at:

  git://github.com/stefanha/qemu.git tags/block-pull-request

for you to fetch changes up to 4cba4284918145de66e27959725559f8aaf764ef:

  NVMe: Set correct VS Value for 1.1 Compliant Controllers (2015-01-09 10:12:23 +0000)

----------------------------------------------------------------

----------------------------------------------------------------

Alex Friedman (1):
  nvme: Fix get/set number of queues feature

Anubhav Rakshit (1):
  NVMe: Set correct VS Value for 1.1 Compliant Controllers

Chrysostomos Nanakos (1):
  MAINTAINERS: Update email addresses for Chrysostomos Nanakos

Fam Zheng (7):
  .gitignore: Ignore generated "common.env"
  qemu-iotests: Replace "/bin/true" with "true"
  qemu-iotests: Add "_supported_os Linux" to 058
  tests/Makefile: Add check-block to make check on Linux
  qemu-iotests: Add supported os parameter for python tests
  block: Split BLOCK_OP_TYPE_COMMIT to BLOCK_OP_TYPE_COMMIT_{SOURCE,
    TARGET}
  MAINTAINERS: Add migration/block* to block subsystem

John Snow (1):
  ide: Implement VPD response for ATAPI

Marc Marí (6):
  libqos: Convert malloc-pc allocator to a generic allocator
  libqos: Change use of pointers to uint64_t in virtio
  tests: Prepare virtio-blk-test for multi-arch implementation
  libqos: Remove PCI assumptions in constants of virtio driver
  libqos: Add malloc generic
  libqos: Add virtio MMIO support

Paolo Bonzini (6):
  coroutine-ucontext: use __thread
  qemu-thread: add per-thread atexit functions
  test-coroutine: avoid overflow on 32-bit systems
  QSLIST: add lock-free operations
  coroutine: rewrite pool to avoid mutex
  coroutine: drop qemu_coroutine_adjust_pool_size

Peter Lieven (2):
  coroutine: try harder not to delete coroutines
  block: limited request size in write zeroes unsupported path

Programmingkid (1):
  block/raw-posix.c: Fixes raw_getlength() on Mac OS X so that it
    reports the correct length of a real CD

 .gitignore                       |   1 +
 MAINTAINERS                      |   2 +-
 block.c                          |  11 +-
 block/block-backend.c            |   4 -
 block/raw-posix.c                |  18 ++-
 blockdev.c                       |   6 +-
 configure                        |   2 +-
 coroutine-ucontext.c             |  69 +++-------
 hw/block/dataplane/virtio-blk.c  |   3 +-
 hw/block/nvme.c                  |   8 +-
 hw/ide/atapi.c                   | 111 ++++++++++++++--
 hw/ide/internal.h                |   1 +
 include/block/block.h            |   3 +-
 include/block/coroutine.h        |  10 --
 include/qemu/queue.h             |  15 ++-
 include/qemu/thread.h            |   4 +
 qemu-coroutine.c                 | 103 +++++++-------
 tests/Makefile                   |   9 +-
 tests/libqos/malloc-generic.c    |  50 +++++++
 tests/libqos/malloc-generic.h    |  21 +++
 tests/libqos/malloc-pc.c         | 280 +--------------------------------------
 tests/libqos/malloc-pc.h         |  11 +-
 tests/libqos/malloc.c            | 270 +++++++++++++++++++++++++++++++++++++
 tests/libqos/malloc.h            |  45 ++++---
 tests/libqos/virtio-mmio.c       | 190 ++++++++++++++++++++++++++
 tests/libqos/virtio-mmio.h       |  46 +++++++
 tests/libqos/virtio-pci.c        |  50 +++----
 tests/libqos/virtio-pci.h        |  24 ++--
 tests/libqos/virtio.c            |   8 +-
 tests/libqos/virtio.h            |  16 +--
 tests/qemu-iotests/058           |   1 +
 tests/qemu-iotests/common.config |   2 +-
 tests/qemu-iotests/common.filter |   2 +-
 tests/qemu-iotests/common.rc     |   2 +-
 tests/qemu-iotests/iotests.py    |   5 +-
 tests/test-coroutine.c           |   2 +-
 tests/virtio-blk-test.c          | 249 +++++++++++++++++++++++-----------
 util/qemu-thread-posix.c         |  37 ++++++
 util/qemu-thread-win32.c         |  48 +++++--
 39 files changed, 1154 insertions(+), 585 deletions(-)
 create mode 100644 tests/libqos/malloc-generic.c
 create mode 100644 tests/libqos/malloc-generic.h
 create mode 100644 tests/libqos/malloc.c
 create mode 100644 tests/libqos/virtio-mmio.c
 create mode 100644 tests/libqos/virtio-mmio.h

-- 
2.1.0

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

* Re: [Qemu-devel] [PULL 00/26] Block patches
  2015-01-09 10:16 Stefan Hajnoczi
@ 2015-01-10 19:05 ` Peter Maydell
  2015-01-10 19:10   ` Peter Maydell
  2015-01-12 14:25   ` Stefan Hajnoczi
  0 siblings, 2 replies; 42+ messages in thread
From: Peter Maydell @ 2015-01-10 19:05 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: QEMU Developers

On 9 January 2015 at 10:16, Stefan Hajnoczi <stefanha@redhat.com> wrote:
> This pull request depends on the previous block pull request which has not been
> merged yet.  It was sent on Monday, 5th of January (Message-id:
> <1420458696-1885-1-git-send-email-stefanha@redhat.com>).
>
> The following changes since commit 3bd54e576f40f1d5bf45b4828c7316efd76a4db6:
>
>   migration/block: fix pending() return value (2015-01-05 11:34:52 +0000)
>
> are available in the git repository at:
>
>   git://github.com/stefanha/qemu.git tags/block-pull-request
>
> for you to fetch changes up to 4cba4284918145de66e27959725559f8aaf764ef:
>
>   NVMe: Set correct VS Value for 1.1 Compliant Controllers (2015-01-09 10:12:23 +0000)

I'm confused. You say this pull depends on the other one, but
the emails give the same tag name for both, so I can't pull
the other one first. (In fact, if not for this one failing I
would have applied it under the assumption that it *was* the
previous pullreq...)

In any case, this one fails 'make check':

GTESTER check-qtest-arm
WARNING: Image format was not specified for '/tmp/qtest.ZDWVz0' and
probing guessed raw.
         Automatically detecting the format is dangerous for raw
images, write operations on block 0 will be restricted.
         Specify the 'raw' format explicitly to remove the restrictions.
**
ERROR:/home/petmay01/linaro/qemu-for-merges/tests/libqos/virtio.c:91:qvirtio_wait_queue_isr:
assertion failed: (g_get_monotonic_time() - start_time <= timeout_us)
GTester: last random seed: R02Scf242b6e43396cc299f6f06431644f8f
make: *** [check-qtest-arm] Error 1
make: Leaving directory `/home/petmay01/linaro/qemu-for-merges/build/all'

thanks
-- PMM

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

* Re: [Qemu-devel] [PULL 00/26] Block patches
  2015-01-10 19:05 ` Peter Maydell
@ 2015-01-10 19:10   ` Peter Maydell
  2015-01-12  9:52     ` Fam Zheng
  2015-01-12 14:25   ` Stefan Hajnoczi
  1 sibling, 1 reply; 42+ messages in thread
From: Peter Maydell @ 2015-01-10 19:10 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: QEMU Developers

On 10 January 2015 at 19:05, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 9 January 2015 at 10:16, Stefan Hajnoczi <stefanha@redhat.com> wrote:
>> This pull request depends on the previous block pull request which has not been
>> merged yet.  It was sent on Monday, 5th of January (Message-id:
>> <1420458696-1885-1-git-send-email-stefanha@redhat.com>).
>>
>> The following changes since commit 3bd54e576f40f1d5bf45b4828c7316efd76a4db6:
>>
>>   migration/block: fix pending() return value (2015-01-05 11:34:52 +0000)
>>
>> are available in the git repository at:
>>
>>   git://github.com/stefanha/qemu.git tags/block-pull-request
>>
>> for you to fetch changes up to 4cba4284918145de66e27959725559f8aaf764ef:
>>
>>   NVMe: Set correct VS Value for 1.1 Compliant Controllers (2015-01-09 10:12:23 +0000)
>
> I'm confused. You say this pull depends on the other one, but
> the emails give the same tag name for both, so I can't pull
> the other one first. (In fact, if not for this one failing I
> would have applied it under the assumption that it *was* the
> previous pullreq...)
>
> In any case, this one fails 'make check':

Failed also and differently on my 32 bit ARM board, though that
may just be because I run this set with V=1; last part
of the log below. Looks like something is trying to run
qemu-system-arm without specifying a machine to use...

 === Testing plain filename for blkdebug ===

-blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT

 === Testing plain filename for blkdebug without configuration file ===

-blkdebug::TEST_DIR/t.IMGFMT
 *** done
100                [20:40:41] [20:40:45]
101                [20:40:45] [20:40:45] [not run]
        101 -- not suitable for this image format: qcow2
102                [20:40:45] [20:40:46] [failed, exit status 141] -
output mismatch (see 102.out.bad)
--- /root/qemu/tests/qemu-iotests/102.out       2014-11-03
18:34:23.000000000 +0000
+++ 102.out.bad 2015-01-09 20:40:46.000000000 +0000
@@ -15,7 +15,6 @@
 wrote 65536/65536 bytes at offset 0
 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 Image resized.
-QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qemu-io drv0 map
-[                       0]      128/     128 sectors     allocated at
offset 0 bytes (1)
-*** done
+No machine specified, and there is no default.
+Use -machine help to list supported machines!
+Timeout waiting for allocated on handle 0
103                [20:40:46] [20:40:47]
105                [20:40:47] [20:40:48]
107                [20:40:48] [20:40:49]
108                [20:40:49] [20:40:52]
110                [20:40:52] [20:40:53]
111                [20:40:53] [20:40:53]
113                [20:40:53] [20:40:53] [not run]
        113 -- not suitable for this image format: qcow2
114                [20:40:53] [20:40:54]
Not run: 016 045 059 064 065 070 075 077 078 081 084 088 092 101 113
Failures: 028 067 068 071 087 095 099 102
Failed 8 of 65 tests
make: *** [check-tests/qemu-iotests-quick.sh] Error 1


-- PMM

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

* Re: [Qemu-devel] [PULL 00/26] Block patches
  2015-01-10 19:10   ` Peter Maydell
@ 2015-01-12  9:52     ` Fam Zheng
  2015-01-12 10:32       ` Paolo Bonzini
  0 siblings, 1 reply; 42+ messages in thread
From: Fam Zheng @ 2015-01-12  9:52 UTC (permalink / raw)
  To: Stefan Hajnoczi, Peter Maydell; +Cc: QEMU Developers

On Sat, 01/10 19:10, Peter Maydell wrote:
> On 10 January 2015 at 19:05, Peter Maydell <peter.maydell@linaro.org> wrote:
> > On 9 January 2015 at 10:16, Stefan Hajnoczi <stefanha@redhat.com> wrote:
> >> This pull request depends on the previous block pull request which has not been
> >> merged yet.  It was sent on Monday, 5th of January (Message-id:
> >> <1420458696-1885-1-git-send-email-stefanha@redhat.com>).
> >>
> >> The following changes since commit 3bd54e576f40f1d5bf45b4828c7316efd76a4db6:
> >>
> >>   migration/block: fix pending() return value (2015-01-05 11:34:52 +0000)
> >>
> >> are available in the git repository at:
> >>
> >>   git://github.com/stefanha/qemu.git tags/block-pull-request
> >>
> >> for you to fetch changes up to 4cba4284918145de66e27959725559f8aaf764ef:
> >>
> >>   NVMe: Set correct VS Value for 1.1 Compliant Controllers (2015-01-09 10:12:23 +0000)
> >
> > I'm confused. You say this pull depends on the other one, but
> > the emails give the same tag name for both, so I can't pull
> > the other one first. (In fact, if not for this one failing I
> > would have applied it under the assumption that it *was* the
> > previous pullreq...)
> >
> > In any case, this one fails 'make check':
> 
> Failed also and differently on my 32 bit ARM board, though that
> may just be because I run this set with V=1; last part
> of the log below. Looks like something is trying to run
> qemu-system-arm without specifying a machine to use...
> 

Ouch! This is something that proves really hard to do.

Stefan, please drop the make check-block series in next revision.

Fam

>  === Testing plain filename for blkdebug ===
> 
> -blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT
> 
>  === Testing plain filename for blkdebug without configuration file ===
> 
> -blkdebug::TEST_DIR/t.IMGFMT
>  *** done
> 100                [20:40:41] [20:40:45]
> 101                [20:40:45] [20:40:45] [not run]
>         101 -- not suitable for this image format: qcow2
> 102                [20:40:45] [20:40:46] [failed, exit status 141] -
> output mismatch (see 102.out.bad)
> --- /root/qemu/tests/qemu-iotests/102.out       2014-11-03
> 18:34:23.000000000 +0000
> +++ 102.out.bad 2015-01-09 20:40:46.000000000 +0000
> @@ -15,7 +15,6 @@
>  wrote 65536/65536 bytes at offset 0
>  64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
>  Image resized.
> -QEMU X.Y.Z monitor - type 'help' for more information
> -(qemu) qemu-io drv0 map
> -[                       0]      128/     128 sectors     allocated at
> offset 0 bytes (1)
> -*** done
> +No machine specified, and there is no default.
> +Use -machine help to list supported machines!
> +Timeout waiting for allocated on handle 0
> 103                [20:40:46] [20:40:47]
> 105                [20:40:47] [20:40:48]
> 107                [20:40:48] [20:40:49]
> 108                [20:40:49] [20:40:52]
> 110                [20:40:52] [20:40:53]
> 111                [20:40:53] [20:40:53]
> 113                [20:40:53] [20:40:53] [not run]
>         113 -- not suitable for this image format: qcow2
> 114                [20:40:53] [20:40:54]
> Not run: 016 045 059 064 065 070 075 077 078 081 084 088 092 101 113
> Failures: 028 067 068 071 087 095 099 102
> Failed 8 of 65 tests
> make: *** [check-tests/qemu-iotests-quick.sh] Error 1
> 
> 
> -- PMM
> 

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

* Re: [Qemu-devel] [PULL 00/26] Block patches
  2015-01-12  9:52     ` Fam Zheng
@ 2015-01-12 10:32       ` Paolo Bonzini
  0 siblings, 0 replies; 42+ messages in thread
From: Paolo Bonzini @ 2015-01-12 10:32 UTC (permalink / raw)
  To: Fam Zheng, Stefan Hajnoczi, Peter Maydell; +Cc: QEMU Developers



On 12/01/2015 10:52, Fam Zheng wrote:
> On Sat, 01/10 19:10, Peter Maydell wrote:
>> On 10 January 2015 at 19:05, Peter Maydell <peter.maydell@linaro.org> wrote:
>>> On 9 January 2015 at 10:16, Stefan Hajnoczi <stefanha@redhat.com> wrote:
>>>> This pull request depends on the previous block pull request which has not been
>>>> merged yet.  It was sent on Monday, 5th of January (Message-id:
>>>> <1420458696-1885-1-git-send-email-stefanha@redhat.com>).
>>>>
>>>> The following changes since commit 3bd54e576f40f1d5bf45b4828c7316efd76a4db6:
>>>>
>>>>   migration/block: fix pending() return value (2015-01-05 11:34:52 +0000)
>>>>
>>>> are available in the git repository at:
>>>>
>>>>   git://github.com/stefanha/qemu.git tags/block-pull-request
>>>>
>>>> for you to fetch changes up to 4cba4284918145de66e27959725559f8aaf764ef:
>>>>
>>>>   NVMe: Set correct VS Value for 1.1 Compliant Controllers (2015-01-09 10:12:23 +0000)
>>>
>>> I'm confused. You say this pull depends on the other one, but
>>> the emails give the same tag name for both, so I can't pull
>>> the other one first. (In fact, if not for this one failing I
>>> would have applied it under the assumption that it *was* the
>>> previous pullreq...)
>>>
>>> In any case, this one fails 'make check':
>>
>> Failed also and differently on my 32 bit ARM board, though that
>> may just be because I run this set with V=1; last part
>> of the log below. Looks like something is trying to run
>> qemu-system-arm without specifying a machine to use...
>>
> 
> Ouch! This is something that proves really hard to do.
> 
> Stefan, please drop the make check-block series in next revision.

No need to drop the bug fixes.  One can just drop patch 11
("tests/Makefile: Add check-block to make check on Linux").

Paolo

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

* Re: [Qemu-devel] [PULL 00/26] Block patches
  2015-01-10 19:05 ` Peter Maydell
  2015-01-10 19:10   ` Peter Maydell
@ 2015-01-12 14:25   ` Stefan Hajnoczi
  1 sibling, 0 replies; 42+ messages in thread
From: Stefan Hajnoczi @ 2015-01-12 14:25 UTC (permalink / raw)
  To: Peter Maydell; +Cc: QEMU Developers

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

On Sat, Jan 10, 2015 at 07:05:47PM +0000, Peter Maydell wrote:
> On 9 January 2015 at 10:16, Stefan Hajnoczi <stefanha@redhat.com> wrote:
> > This pull request depends on the previous block pull request which has not been
> > merged yet.  It was sent on Monday, 5th of January (Message-id:
> > <1420458696-1885-1-git-send-email-stefanha@redhat.com>).
> >
> > The following changes since commit 3bd54e576f40f1d5bf45b4828c7316efd76a4db6:
> >
> >   migration/block: fix pending() return value (2015-01-05 11:34:52 +0000)
> >
> > are available in the git repository at:
> >
> >   git://github.com/stefanha/qemu.git tags/block-pull-request
> >
> > for you to fetch changes up to 4cba4284918145de66e27959725559f8aaf764ef:
> >
> >   NVMe: Set correct VS Value for 1.1 Compliant Controllers (2015-01-09 10:12:23 +0000)
> 
> I'm confused. You say this pull depends on the other one, but
> the emails give the same tag name for both, so I can't pull
> the other one first. (In fact, if not for this one failing I
> would have applied it under the assumption that it *was* the
> previous pullreq...)

I used a script that overwrites the pull request tag.

Sorry for the confusion.  You can look at the "for you to fetch changes
up to 4cba4284918145de66e27959725559f8aaf764ef" lines to identify which
commits are part of each pull request.

I'm resending a new (combined) revision without the make check-block
commit.

Stefan

[-- Attachment #2: Type: application/pgp-signature, Size: 473 bytes --]

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

end of thread, other threads:[~2015-01-12 14:25 UTC | newest]

Thread overview: 42+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-09-05 16:13 [Qemu-devel] [PULL 00/26] Block patches Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 01/26] block: kill tail whitespace in block.c Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 02/26] pflash_cfi01: fixup stale DPRINTF() calls Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 03/26] pflash_cfi01: write flash contents to bdrv on incoming migration Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 04/26] virtio: Import virtio_vring.h Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 05/26] block: Always compile virtio-blk dataplane Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 06/26] tests: Functions bus_foreach and device_find from libqos virtio API Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 07/26] tests: Add virtio device initialization Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 08/26] libqos: Added basic virtqueue support to virtio implementation Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 09/26] libqos: Added indirect descriptor " Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 10/26] libqos: Added test case for configuration changes in virtio-blk test Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 11/26] libqos: Added MSI-X support Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 12/26] libqos: Added EVENT_IDX support Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 13/26] qemu-img: clarify src_cache option documentation Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 14/26] qemu-img: fix rebase " Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 15/26] block/archipelago: Use QEMU atomic builtins Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 16/26] rename parse_enum_option to qapi_enum_parse and make it public Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 17/26] qemu-nbd: add option to set detect-zeroes mode Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 18/26] qemu-nbd: fix indentation and coding style Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 19/26] MAINTAINERS: update sheepdog maintainer Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 20/26] libqos: add a simple first-fit memory allocator Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 21/26] qtest/ide: Uninitialize PC allocator Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 22/26] ide: Add wwn support to IDE-ATAPI drive Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 23/26] vmdk: fix vmdk_parse_extents() extent_file leaks Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 24/26] vmdk: fix buf leak in vmdk_parse_extents() Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 25/26] IDE: Fill the IDENTIFY request consistently Stefan Hajnoczi
2014-09-05 16:13 ` [Qemu-devel] [PULL 26/26] ide: Add resize callback to ide/core Stefan Hajnoczi
2014-09-05 16:32 ` [Qemu-devel] [PULL 00/26] Block patches Peter Maydell
  -- strict thread matches above, loose matches on Subject: below --
2015-01-09 10:16 Stefan Hajnoczi
2015-01-10 19:05 ` Peter Maydell
2015-01-10 19:10   ` Peter Maydell
2015-01-12  9:52     ` Fam Zheng
2015-01-12 10:32       ` Paolo Bonzini
2015-01-12 14:25   ` Stefan Hajnoczi
2013-08-30 14:30 Kevin Wolf
2013-08-30 17:14 ` Anthony Liguori
2013-09-02  8:24   ` Kevin Wolf
2013-06-07 11:58 Stefan Hajnoczi
2013-06-17 21:17 ` Anthony Liguori
2012-11-14 18:47 Kevin Wolf
2012-11-19  9:12 ` Kevin Wolf
2010-04-23 15:30 Kevin Wolf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).