mbox series

[RFC,0/5] hmp,qmp: Add some commands to introspect virtio devices

Message ID 20200402100302.833267-1-lvivier@redhat.com
Headers show
Series hmp,qmp: Add some commands to introspect virtio devices | expand

Message

Laurent Vivier April 2, 2020, 10:02 a.m. UTC
This series introduces new QMP/HMP commands to dump the status
of a a virtio device at different levels.

1. Main command

 HMP Only:

     virtio [subcommand]

   Example:

    List all sub-commands:

    (qemu) virtio
    virtio query  -- List all available virtio devices
    virtio status path -- Display status of a given virtio device
    virtio queue-status path queue -- Display status of a given virtio queue
    virtio queue-element path queue [index] -- Display element of a given virtio queue

2. List available virtio devices in the machine

  HMP Form:

    virtio query

  Example:

    (qemu) virtio query
    /machine/peripheral-anon/device[3]/virtio-backend [virtio-net]
    /machine/peripheral-anon/device[1]/virtio-backend [virtio-serial]
    /machine/peripheral-anon/device[0]/virtio-backend [virtio-blk]

  QMP Form:

    { 'command': 'query-virtio', 'returns': ['VirtioInfo'] }

  Example:

  -> { "execute": "query-virtio" }
  <- { "return": [
         {
             "path": "/machine/peripheral-anon/device[3]/virtio-backend",
             "type": "virtio-net"
         },
         {
             "path": "/machine/peripheral-anon/device[1]/virtio-backend",
             "type": "virtio-serial"
         },
         {
             "path": "/machine/peripheral-anon/device[0]/virtio-backend",
             "type": "virtio-blk"
         }
       ]
     }

3. Display status of a given virtio device

  HMP Form:

    virtio status <path>

  Example:

    (qemu) virtio status /machine/peripheral-anon/device[3]/virtio-backend
    /machine/peripheral-anon/device[3]/virtio-backend:
      Device Id:        1
      Guest features:   0x0000000130afffa7
      Host features:    0x0000000179bfffe7
      Backend features: 0x0000000000000000
      Endianness:       little
      VirtQueues:       3

  QMP Form:

    { 'command': 'virtio-status',
      'data': { 'path': 'str' },
      'returns': 'VirtioStatus'
    }

  Example:

  -> { "execute": "virtio-status",
       "arguments": {
           "path": "/machine/peripheral-anon/device[3]/virtio-backend"
       }
    }
  <- { "return": {
           "backend_features": 0,
           "guest_features": 5111807911,
           "num_vqs": 3,
           "host_features": 6337593319,
           "device_endian": "little",
           "device_id": 1
       }
     }

4. Display status of a given virtio queue

  HMP Form:

    virtio queue-status <path> <queue>

  Example:

    (qemu) virtio queue-status /machine/peripheral-anon/device[3]/virtio-backend 0
    /machine/peripheral-anon/device[3]/virtio-backend:
      index:                0
      inuse:                0
      last_avail_idx:       61
      shadow_avail_idx:     292
      signalled_used:       61
      signalled_used_valid: 1
      VRing:
        num:         256
        num_default: 256
        align:       4096
        desc:        0x000000006c352000
        avail:       0x000000006c353000
        used:        0x000000006c353240

  QMP Form:

    { 'command': 'virtio-queue-status',
      'data': { 'path': 'str', 'queue': 'uint16' },
      'returns': 'VirtQueueStatus'
    }

  Example:

  -> { "execute": "virtio-queue-status",
       "arguments": {
           "path": "/machine/peripheral-anon/device[3]/virtio-backend",
           "queue": 0
       }
    }
  <- { "return": {
       "signalled_used": 373,
       "inuse": 0,
       "vring_desc": 864411648,
       "vring_num_default": 256,
       "signalled_used_valid": 1,
       "vring_avail": 864415744,
       "last_avail_idx": 373,
       "queue_index": 0,
       "vring_used": 864416320,
       "shadow_avail_idx": 619,
       "used_idx": 373,
       "vring_num": 256,
       "vring_align": 4096
       }
     }

5. Display element of a given virtio queue

  HMP Form:

    virtio queue-element <path> <queue> [index]

  Example:

    Dump the information of the head element of the first queue of
    the first virtio device::

      (qemu) virtio queue-element/machine/peripheral-anon/device[3]/virtio-backend 0
      index:  67
      ndescs: 1
      descs:  addr 0x6fe69800 len 1536 (write-only)

      (qemu) xp/128bx 0x6fe69800
      000000006fe69800: 0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x00
      000000006fe69808: 0x00 0x00 0x01 0x00 0x52 0x54 0x00 0x12
      000000006fe69810: 0x34 0x56 0x52 0x54 0x00 0x09 0x51 0xde
      000000006fe69818: 0x08 0x00 0x45 0x00 0x00 0x4c 0x8f 0x32

    device[3] is a virtio-net device and we can see in the element buffer the
    MAC address of the card::

      [root@localhost ~]# ip link show ens4
      2: ens4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP m0
          link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff

    and the MAC address of the gateway::

      [root@localhost ~]# arp -a
      _gateway (192.168.122.1) at 52:54:00:09:51:de [ether] on ens4

  QMP Form:

    { 'command': 'virtio-queue-element',
      'data': { 'path': 'str', 'queue': 'uint16', '*index': 'uint16' },
      'returns': 'VirtioQueueElement'
    }

  Example:

  -> { "execute": "virtio-queue-element",
       "arguments": {
           "path": "/machine/peripheral-anon/device[3]/virtio-backend",
           "queue": 0
       }
    }
  -> { "return": {
          "index": 109,
          "len": 0,
          "ndescs": 1,
          "descs": [
              { "flags": 2, "len": 2048, "addr": 853145600 }
          ]
       }
    }

Laurent Vivier (5):
  qmp: add QMP command query-virtio
  qmp: add QMP command virtio-status
  qmp: add QMP command virtio-queue-status
  qmp: add QMP command virtio-queue-element
  hmp: add virtio commands

 Makefile                   |   2 +-
 Makefile.target            |   7 +-
 docs/system/monitor.rst    |   2 +
 hmp-commands-virtio.hx     | 148 ++++++++++++++++++
 hmp-commands.hx            |  10 ++
 hw/virtio/Makefile.objs    |   2 +
 hw/virtio/virtio-stub.c    |  32 ++++
 hw/virtio/virtio.c         | 313 +++++++++++++++++++++++++++++++++++++
 include/hw/virtio/virtio.h |   1 +
 include/monitor/hmp.h      |   4 +
 monitor/misc.c             |  17 ++
 qapi/Makefile.objs         |   2 +-
 qapi/qapi-schema.json      |   1 +
 qapi/virtio.json           | 302 +++++++++++++++++++++++++++++++++++
 tests/qtest/qmp-cmd-test.c |   1 +
 15 files changed, 840 insertions(+), 4 deletions(-)
 create mode 100644 hmp-commands-virtio.hx
 create mode 100644 hw/virtio/virtio-stub.c
 create mode 100644 qapi/virtio.json

Comments

Marc-André Lureau April 2, 2020, 2:33 p.m. UTC | #1
Hi

On Thu, Apr 2, 2020 at 12:03 PM Laurent Vivier <lvivier@redhat.com> wrote:
>
> This series introduces new QMP/HMP commands to dump the status
> of a a virtio device at different levels.

Looks nice, but my feeling is that we are growing qemu with debugging
facilities in general with HMP/QMP.

If this is only for debugging purposes, why don't we compile it only
when --enable-debug?

A guest that would need to be debugged could have its state loaded in
a debug version of qemu.

Alternatively, I think most of the data you provide here could
probably be introspected via gdb scripts.

Just some thoughts

>
> 1. Main command
>
>  HMP Only:
>
>      virtio [subcommand]
>
>    Example:
>
>     List all sub-commands:
>
>     (qemu) virtio
>     virtio query  -- List all available virtio devices
>     virtio status path -- Display status of a given virtio device
>     virtio queue-status path queue -- Display status of a given virtio queue
>     virtio queue-element path queue [index] -- Display element of a given virtio queue
>
> 2. List available virtio devices in the machine
>
>   HMP Form:
>
>     virtio query
>
>   Example:
>
>     (qemu) virtio query
>     /machine/peripheral-anon/device[3]/virtio-backend [virtio-net]
>     /machine/peripheral-anon/device[1]/virtio-backend [virtio-serial]
>     /machine/peripheral-anon/device[0]/virtio-backend [virtio-blk]
>
>   QMP Form:
>
>     { 'command': 'query-virtio', 'returns': ['VirtioInfo'] }
>
>   Example:
>
>   -> { "execute": "query-virtio" }
>   <- { "return": [
>          {
>              "path": "/machine/peripheral-anon/device[3]/virtio-backend",
>              "type": "virtio-net"
>          },
>          {
>              "path": "/machine/peripheral-anon/device[1]/virtio-backend",
>              "type": "virtio-serial"
>          },
>          {
>              "path": "/machine/peripheral-anon/device[0]/virtio-backend",
>              "type": "virtio-blk"
>          }
>        ]
>      }
>
> 3. Display status of a given virtio device
>
>   HMP Form:
>
>     virtio status <path>
>
>   Example:
>
>     (qemu) virtio status /machine/peripheral-anon/device[3]/virtio-backend
>     /machine/peripheral-anon/device[3]/virtio-backend:
>       Device Id:        1
>       Guest features:   0x0000000130afffa7
>       Host features:    0x0000000179bfffe7
>       Backend features: 0x0000000000000000
>       Endianness:       little
>       VirtQueues:       3
>
>   QMP Form:
>
>     { 'command': 'virtio-status',
>       'data': { 'path': 'str' },
>       'returns': 'VirtioStatus'
>     }
>
>   Example:
>
>   -> { "execute": "virtio-status",
>        "arguments": {
>            "path": "/machine/peripheral-anon/device[3]/virtio-backend"
>        }
>     }
>   <- { "return": {
>            "backend_features": 0,
>            "guest_features": 5111807911,
>            "num_vqs": 3,
>            "host_features": 6337593319,
>            "device_endian": "little",
>            "device_id": 1
>        }
>      }
>
> 4. Display status of a given virtio queue
>
>   HMP Form:
>
>     virtio queue-status <path> <queue>
>
>   Example:
>
>     (qemu) virtio queue-status /machine/peripheral-anon/device[3]/virtio-backend 0
>     /machine/peripheral-anon/device[3]/virtio-backend:
>       index:                0
>       inuse:                0
>       last_avail_idx:       61
>       shadow_avail_idx:     292
>       signalled_used:       61
>       signalled_used_valid: 1
>       VRing:
>         num:         256
>         num_default: 256
>         align:       4096
>         desc:        0x000000006c352000
>         avail:       0x000000006c353000
>         used:        0x000000006c353240
>
>   QMP Form:
>
>     { 'command': 'virtio-queue-status',
>       'data': { 'path': 'str', 'queue': 'uint16' },
>       'returns': 'VirtQueueStatus'
>     }
>
>   Example:
>
>   -> { "execute": "virtio-queue-status",
>        "arguments": {
>            "path": "/machine/peripheral-anon/device[3]/virtio-backend",
>            "queue": 0
>        }
>     }
>   <- { "return": {
>        "signalled_used": 373,
>        "inuse": 0,
>        "vring_desc": 864411648,
>        "vring_num_default": 256,
>        "signalled_used_valid": 1,
>        "vring_avail": 864415744,
>        "last_avail_idx": 373,
>        "queue_index": 0,
>        "vring_used": 864416320,
>        "shadow_avail_idx": 619,
>        "used_idx": 373,
>        "vring_num": 256,
>        "vring_align": 4096
>        }
>      }
>
> 5. Display element of a given virtio queue
>
>   HMP Form:
>
>     virtio queue-element <path> <queue> [index]
>
>   Example:
>
>     Dump the information of the head element of the first queue of
>     the first virtio device::
>
>       (qemu) virtio queue-element/machine/peripheral-anon/device[3]/virtio-backend 0
>       index:  67
>       ndescs: 1
>       descs:  addr 0x6fe69800 len 1536 (write-only)
>
>       (qemu) xp/128bx 0x6fe69800
>       000000006fe69800: 0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x00
>       000000006fe69808: 0x00 0x00 0x01 0x00 0x52 0x54 0x00 0x12
>       000000006fe69810: 0x34 0x56 0x52 0x54 0x00 0x09 0x51 0xde
>       000000006fe69818: 0x08 0x00 0x45 0x00 0x00 0x4c 0x8f 0x32
>
>     device[3] is a virtio-net device and we can see in the element buffer the
>     MAC address of the card::
>
>       [root@localhost ~]# ip link show ens4
>       2: ens4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP m0
>           link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff
>
>     and the MAC address of the gateway::
>
>       [root@localhost ~]# arp -a
>       _gateway (192.168.122.1) at 52:54:00:09:51:de [ether] on ens4
>
>   QMP Form:
>
>     { 'command': 'virtio-queue-element',
>       'data': { 'path': 'str', 'queue': 'uint16', '*index': 'uint16' },
>       'returns': 'VirtioQueueElement'
>     }
>
>   Example:
>
>   -> { "execute": "virtio-queue-element",
>        "arguments": {
>            "path": "/machine/peripheral-anon/device[3]/virtio-backend",
>            "queue": 0
>        }
>     }
>   -> { "return": {
>           "index": 109,
>           "len": 0,
>           "ndescs": 1,
>           "descs": [
>               { "flags": 2, "len": 2048, "addr": 853145600 }
>           ]
>        }
>     }
>
> Laurent Vivier (5):
>   qmp: add QMP command query-virtio
>   qmp: add QMP command virtio-status
>   qmp: add QMP command virtio-queue-status
>   qmp: add QMP command virtio-queue-element
>   hmp: add virtio commands
>
>  Makefile                   |   2 +-
>  Makefile.target            |   7 +-
>  docs/system/monitor.rst    |   2 +
>  hmp-commands-virtio.hx     | 148 ++++++++++++++++++
>  hmp-commands.hx            |  10 ++
>  hw/virtio/Makefile.objs    |   2 +
>  hw/virtio/virtio-stub.c    |  32 ++++
>  hw/virtio/virtio.c         | 313 +++++++++++++++++++++++++++++++++++++
>  include/hw/virtio/virtio.h |   1 +
>  include/monitor/hmp.h      |   4 +
>  monitor/misc.c             |  17 ++
>  qapi/Makefile.objs         |   2 +-
>  qapi/qapi-schema.json      |   1 +
>  qapi/virtio.json           | 302 +++++++++++++++++++++++++++++++++++
>  tests/qtest/qmp-cmd-test.c |   1 +
>  15 files changed, 840 insertions(+), 4 deletions(-)
>  create mode 100644 hmp-commands-virtio.hx
>  create mode 100644 hw/virtio/virtio-stub.c
>  create mode 100644 qapi/virtio.json
>
> --
> 2.25.1
>
>
Dr. David Alan Gilbert April 2, 2020, 3:23 p.m. UTC | #2
* Marc-André Lureau (marcandre.lureau@gmail.com) wrote:
> Hi
> 
> On Thu, Apr 2, 2020 at 12:03 PM Laurent Vivier <lvivier@redhat.com> wrote:
> >
> > This series introduces new QMP/HMP commands to dump the status
> > of a a virtio device at different levels.
> 
> Looks nice, but my feeling is that we are growing qemu with debugging
> facilities in general with HMP/QMP.
> 
> If this is only for debugging purposes, why don't we compile it only
> when --enable-debug?
> 
> A guest that would need to be debugged could have its state loaded in
> a debug version of qemu.
> 
> Alternatively, I think most of the data you provide here could
> probably be introspected via gdb scripts.
> 
> Just some thoughts

I kind of agree, but virtio is bread-and-butter, so having it available
all the time isn't a bad idea; however having said that hte same
argument would be for why having gdb scripts to examine your virtio
queues would be useful if you're dealing with a core.

Dave

> 
> >
> > 1. Main command
> >
> >  HMP Only:
> >
> >      virtio [subcommand]
> >
> >    Example:
> >
> >     List all sub-commands:
> >
> >     (qemu) virtio
> >     virtio query  -- List all available virtio devices
> >     virtio status path -- Display status of a given virtio device
> >     virtio queue-status path queue -- Display status of a given virtio queue
> >     virtio queue-element path queue [index] -- Display element of a given virtio queue
> >
> > 2. List available virtio devices in the machine
> >
> >   HMP Form:
> >
> >     virtio query
> >
> >   Example:
> >
> >     (qemu) virtio query
> >     /machine/peripheral-anon/device[3]/virtio-backend [virtio-net]
> >     /machine/peripheral-anon/device[1]/virtio-backend [virtio-serial]
> >     /machine/peripheral-anon/device[0]/virtio-backend [virtio-blk]
> >
> >   QMP Form:
> >
> >     { 'command': 'query-virtio', 'returns': ['VirtioInfo'] }
> >
> >   Example:
> >
> >   -> { "execute": "query-virtio" }
> >   <- { "return": [
> >          {
> >              "path": "/machine/peripheral-anon/device[3]/virtio-backend",
> >              "type": "virtio-net"
> >          },
> >          {
> >              "path": "/machine/peripheral-anon/device[1]/virtio-backend",
> >              "type": "virtio-serial"
> >          },
> >          {
> >              "path": "/machine/peripheral-anon/device[0]/virtio-backend",
> >              "type": "virtio-blk"
> >          }
> >        ]
> >      }
> >
> > 3. Display status of a given virtio device
> >
> >   HMP Form:
> >
> >     virtio status <path>
> >
> >   Example:
> >
> >     (qemu) virtio status /machine/peripheral-anon/device[3]/virtio-backend
> >     /machine/peripheral-anon/device[3]/virtio-backend:
> >       Device Id:        1
> >       Guest features:   0x0000000130afffa7
> >       Host features:    0x0000000179bfffe7
> >       Backend features: 0x0000000000000000
> >       Endianness:       little
> >       VirtQueues:       3
> >
> >   QMP Form:
> >
> >     { 'command': 'virtio-status',
> >       'data': { 'path': 'str' },
> >       'returns': 'VirtioStatus'
> >     }
> >
> >   Example:
> >
> >   -> { "execute": "virtio-status",
> >        "arguments": {
> >            "path": "/machine/peripheral-anon/device[3]/virtio-backend"
> >        }
> >     }
> >   <- { "return": {
> >            "backend_features": 0,
> >            "guest_features": 5111807911,
> >            "num_vqs": 3,
> >            "host_features": 6337593319,
> >            "device_endian": "little",
> >            "device_id": 1
> >        }
> >      }
> >
> > 4. Display status of a given virtio queue
> >
> >   HMP Form:
> >
> >     virtio queue-status <path> <queue>
> >
> >   Example:
> >
> >     (qemu) virtio queue-status /machine/peripheral-anon/device[3]/virtio-backend 0
> >     /machine/peripheral-anon/device[3]/virtio-backend:
> >       index:                0
> >       inuse:                0
> >       last_avail_idx:       61
> >       shadow_avail_idx:     292
> >       signalled_used:       61
> >       signalled_used_valid: 1
> >       VRing:
> >         num:         256
> >         num_default: 256
> >         align:       4096
> >         desc:        0x000000006c352000
> >         avail:       0x000000006c353000
> >         used:        0x000000006c353240
> >
> >   QMP Form:
> >
> >     { 'command': 'virtio-queue-status',
> >       'data': { 'path': 'str', 'queue': 'uint16' },
> >       'returns': 'VirtQueueStatus'
> >     }
> >
> >   Example:
> >
> >   -> { "execute": "virtio-queue-status",
> >        "arguments": {
> >            "path": "/machine/peripheral-anon/device[3]/virtio-backend",
> >            "queue": 0
> >        }
> >     }
> >   <- { "return": {
> >        "signalled_used": 373,
> >        "inuse": 0,
> >        "vring_desc": 864411648,
> >        "vring_num_default": 256,
> >        "signalled_used_valid": 1,
> >        "vring_avail": 864415744,
> >        "last_avail_idx": 373,
> >        "queue_index": 0,
> >        "vring_used": 864416320,
> >        "shadow_avail_idx": 619,
> >        "used_idx": 373,
> >        "vring_num": 256,
> >        "vring_align": 4096
> >        }
> >      }
> >
> > 5. Display element of a given virtio queue
> >
> >   HMP Form:
> >
> >     virtio queue-element <path> <queue> [index]
> >
> >   Example:
> >
> >     Dump the information of the head element of the first queue of
> >     the first virtio device::
> >
> >       (qemu) virtio queue-element/machine/peripheral-anon/device[3]/virtio-backend 0
> >       index:  67
> >       ndescs: 1
> >       descs:  addr 0x6fe69800 len 1536 (write-only)
> >
> >       (qemu) xp/128bx 0x6fe69800
> >       000000006fe69800: 0x02 0x00 0x00 0x00 0x00 0x00 0x00 0x00
> >       000000006fe69808: 0x00 0x00 0x01 0x00 0x52 0x54 0x00 0x12
> >       000000006fe69810: 0x34 0x56 0x52 0x54 0x00 0x09 0x51 0xde
> >       000000006fe69818: 0x08 0x00 0x45 0x00 0x00 0x4c 0x8f 0x32
> >
> >     device[3] is a virtio-net device and we can see in the element buffer the
> >     MAC address of the card::
> >
> >       [root@localhost ~]# ip link show ens4
> >       2: ens4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP m0
> >           link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff
> >
> >     and the MAC address of the gateway::
> >
> >       [root@localhost ~]# arp -a
> >       _gateway (192.168.122.1) at 52:54:00:09:51:de [ether] on ens4
> >
> >   QMP Form:
> >
> >     { 'command': 'virtio-queue-element',
> >       'data': { 'path': 'str', 'queue': 'uint16', '*index': 'uint16' },
> >       'returns': 'VirtioQueueElement'
> >     }
> >
> >   Example:
> >
> >   -> { "execute": "virtio-queue-element",
> >        "arguments": {
> >            "path": "/machine/peripheral-anon/device[3]/virtio-backend",
> >            "queue": 0
> >        }
> >     }
> >   -> { "return": {
> >           "index": 109,
> >           "len": 0,
> >           "ndescs": 1,
> >           "descs": [
> >               { "flags": 2, "len": 2048, "addr": 853145600 }
> >           ]
> >        }
> >     }
> >
> > Laurent Vivier (5):
> >   qmp: add QMP command query-virtio
> >   qmp: add QMP command virtio-status
> >   qmp: add QMP command virtio-queue-status
> >   qmp: add QMP command virtio-queue-element
> >   hmp: add virtio commands
> >
> >  Makefile                   |   2 +-
> >  Makefile.target            |   7 +-
> >  docs/system/monitor.rst    |   2 +
> >  hmp-commands-virtio.hx     | 148 ++++++++++++++++++
> >  hmp-commands.hx            |  10 ++
> >  hw/virtio/Makefile.objs    |   2 +
> >  hw/virtio/virtio-stub.c    |  32 ++++
> >  hw/virtio/virtio.c         | 313 +++++++++++++++++++++++++++++++++++++
> >  include/hw/virtio/virtio.h |   1 +
> >  include/monitor/hmp.h      |   4 +
> >  monitor/misc.c             |  17 ++
> >  qapi/Makefile.objs         |   2 +-
> >  qapi/qapi-schema.json      |   1 +
> >  qapi/virtio.json           | 302 +++++++++++++++++++++++++++++++++++
> >  tests/qtest/qmp-cmd-test.c |   1 +
> >  15 files changed, 840 insertions(+), 4 deletions(-)
> >  create mode 100644 hmp-commands-virtio.hx
> >  create mode 100644 hw/virtio/virtio-stub.c
> >  create mode 100644 qapi/virtio.json
> >
> > --
> > 2.25.1
> >
> >
> 
> 
> -- 
> Marc-André Lureau
> 
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK