kvm tools: Fix virtio-net iov memcpy

Milan Kocian writes:

  I found the crash in virtio-net-rx thread (I can reproduce it every
  time by 'aptitude update' in VM):

  traps: virtio-net-rx[28933] general protection ip:7f00dda3d107 sp:7f00c58f4de8 error:0 in libc-2.17.so[7f00dd90f000+1a2000]

  gdb backtrace:

  (gdb) bt
  #0  0x00007fb6a548e107 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
  #1  0x000000000041259c in memcpy_toiovecend (iov=0x7fb68d346ea0, iov@entry=0x7fb68d345e90,
      kdata=<optimized out>, kdata@entry=0x7fb68d346e90 "", offset=<optimized out>, len=<optimized out>)
      at util/iovec.c:70
  #2  0x000000000040c66d in virtio_net_rx_thread (p=0x23688a0) at virtio/net.c:117
  #3  0x00007fb6a5b2ee0e in start_thread () from /lib/x86_64-linux-gnu/libpthread.so.0
  #4  0x00007fb6a54489ed in clone () from /lib/x86_64-linux-gnu/libc.so.6

  I tried to add some printf to diagnose it but it isn't clear to me:

  virtio_net_rx_thread: before memcpy_toiovecend; copied: 0, len: 18890, iovsize: 4096, realiovsize: 4096
  memcpy_toiovecend: offset: 0, len: 4096
  memcpy_toiovecend: iov_len: 4096, len: 4096
  virtio_net_rx_thread: before memcpy_toiovecend; copied: 4096, len: 18890, iovsize: 4096, realiovsize: 4096
  memcpy_toiovecend: offset: 4096, len: 4096
  memcpy_toiovecend: iov_len: 4096, len: 4096
  memcpy_toiovecend: iov_len: 0, len: 4096
  memcpy_toiovecend: iov_len: 0, len: 4096
  .
  N x memcpy_toiovecend: iov_len: 0, len: 4096
  .
  memcpy_toiovecend: iov_len: 0, len: 4096
  memcpy_toiovecend: iov_len: 0, len: 4096
  memcpy_toiovecend: iov_len: 1519143547641528320, len: 4096
  memcpy_toiovecend: iov_len: 193827583623176, len: 4096
  ./runlkvm.sh: line 2: 16090 Segmentation fault

  IMHO problem come when received len size is bigger than maximum of the
  dst iovec (realiovsize). Only iovec size is copied and in the next run
  isn't place to copy the rest of len size.

Asias He writes:

  We should skip copied bytes from the buffer not from the iov itself
  which memcpy_toiovecend does.

Reported-and-tested-by: Milan Kocian <milon@wq.cz>
Signed-off-by: Asias He <asias.hejun@gmail.com>
Signed-off-by: Pekka Enberg <penberg@iki.fi>
This commit is contained in:
Asias He
2013-10-28 15:02:54 +08:00
committed by Will Deacon
parent 97bb5a9dfb
commit e249304721
+1 -1
View File
@@ -114,7 +114,7 @@ static void *virtio_net_rx_thread(void *p)
while (copied < len) {
size_t iovsize = min(len - copied, iov_size(iov, in));
memcpy_toiovecend(iov, buffer, copied, iovsize);
memcpy_toiovec(iov, buffer + copied, iovsize);
copied += iovsize;
if (has_virtio_feature(ndev, VIRTIO_NET_F_MRG_RXBUF))
hdr->num_buffers++;