All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paul Guo <ggang@tilera.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] qemu/virtio issue due to non-atomic data access
Date: Thu, 2 May 2013 17:12:31 +0800	[thread overview]
Message-ID: <51822DFF.4070300@tilera.com> (raw)

Hello,

I'm developing the qemu io support for kvm on arch/tile. During virtio-net testing I always saw the following similar message:

"Guest moved used index from 46573 to 46592"

The guest os then exits immediately. The qemu version is 0.13.0.

Here is the code that reports the error message:

static int virtqueue_num_heads(VirtQueue *vq, unsigned int idx)
{
    uint16_t num_heads = vring_avail_idx(vq) - idx;

    /* Check it isn't doing very strange things with descriptor numbers. */
    if (num_heads > vq->vring.num) {
        fprintf(stderr, "Guest moved used index from %u to %u",
                idx, vring_avail_idx(vq));
        exit(1);
    }

    return num_heads;
}

I looked into this issue a bit, it seems that this is due to the non-atomic data access of some virtio variables in qemu. In the above case, vq->vring.avail.idx is modified by kernel and is read in qemu via lduw_le_p() (for our default hw configuration case). lduw_le_p() loads the 16bit values byte by byte. If the kernel is updating the value from 0xB5FF to 0xB600 (i.e. 46592), qemu probably reads 0xB6FF and then virtqueue_num_heads() enters the error handling branch.

static inline int lduw_le_p(const void *ptr)
{
#ifdef _ARCH_PPC
    int val;
    __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
    return val;
#else
    const uint8_t *p = ptr;
    return p[0] | (p[1] << 8);
#endif
}

Latest qemu changes to use memcpy() in lduw_le_p(), but if the alignment of the destination pointer in memcpy() is not implied, the compiler will probably still have to load byte by byte, thus vring_avail_idx() still has this issue.

A proper fix for this issue seems to be: Judge whether the address is aligned, do direct loading for the aligned case in ldq_le_p(), etc?

Thanks,
Paul

             reply	other threads:[~2013-05-02  9:32 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-05-02  9:12 Paul Guo [this message]
2013-05-02 10:06 ` [Qemu-devel] qemu/virtio issue due to non-atomic data access Richard Henderson
2013-05-03  3:20   ` Paul Guo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=51822DFF.4070300@tilera.com \
    --to=ggang@tilera.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.