public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: "SourceForge.net" <noreply-pyega4qmqnRoyOMFzWx49A@public.gmane.org>
To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
Subject: [ kvm-Bugs-1881532 ] Network access seg faults KVM on large-memory	machine
Date: Mon, 28 Jan 2008 17:16:24 -0800	[thread overview]
Message-ID: <E1JJf5M-00073D-LP@sc8-sf-web23.sourceforge.net> (raw)

Bugs item #1881532, was opened at 2008-01-28 18:16
Message generated for change (Tracker Item Submitted) made by Item Submitter
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=893831&aid=1881532&group_id=180599

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: None
Group: None
Status: Open
Resolution: None
Priority: 5
Private: No
Submitted By: Scott Pakin (pakin)
Assigned to: Nobody/Anonymous (nobody)
Summary: Network access seg faults KVM on large-memory machine

Initial Comment:
The TCP-handling code in qemu/slirp is not 64-bit clean.  On a system
with tons of memory -- I'm running on a system with just under 48GB of
RAM -- KVM dies with a segmentation fault when I try to access the
network.

Specifically, I boot the Ubuntu live CD image, open a terminal, and
try to ssh to the host machine.  KVM segfaults before ssh returns.

For completeness, here are the parameters requested on the "Submitting
a bug report" page:

    CPU model:     Dual-Core AMD Opteron(tm) Processor 8212
    KVM version:   60
    Host kernel:   Linux version 2.6.18-8.1.14.el5 (mockbuild-Bqj+TZ04CV0YyQU+NhOpU0B+6BGkLq7r@public.gmane.org) (gcc version 4.1.1 20070105 (Red Hat 4.1.1-52)) #1 SMP Thu Sep 27 19:05:32 EDT 2007
    Guest arch:    x86_64
    Guest OS:      Ubuntu Linux 7.10
    Guest bitness: 64
    Guest kernel:  Linux version 2.6.22-14-generic (buildd@crested) (gcc version 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)) #1 SMP Sun Oct 14 21:45:15 GMT 2007
    Command line:  qemu-system-x86_64 -cdrom ubuntu-7.10-desktop-amd64.iso -boot d -localtime -m 1024
    With -no-kvm:  [still fails]

Fortunately, I managed to track down the problem.  First, note how the
seg_next field is declared in a TCP control block:

    qemu/slirp/tcp_var.h:
      43 #if SIZEOF_CHAR_P == 4
      44  typedef struct tcpiphdr *tcpiphdrp_32;
      45 #else
      46  typedef u_int32_t tcpiphdrp_32;
      47 #endif
      ...
      52 struct tcpcb {
      53         tcpiphdrp_32 seg_next;  /* sequencing queue */
      54         tcpiphdrp_32 seg_prev;

Because this is a 64-bit build, SIZEOF_CHAR_P is 8 so tcpiphdrp_32 --
and hence seg_next -- is defined as a u_int32_t, a 32-bit integer.

Second, note how tp->seg_next is defined:

    qemu/slirp/tcp_subr.c:
      189 tcp_newtcpcb(so)
      190         struct socket *so;
      191 {
      192         register struct tcpcb *tp;
      193
      194         tp = (struct tcpcb *)malloc(sizeof(*tp));
      195         if (tp == NULL)
      196                 return ((struct tcpcb *)0);
      197
      198         memset((char *) tp, 0, sizeof(struct tcpcb));
      199         tp->seg_next = tp->seg_prev = (tcpiphdrp_32)tp;

It's taking a 64-bit pointer, tp, and assigning it to a seg_next
field, which is a 32-bit integer.  Not surprisingly, a SIGSEGV is
generated when that 32-bit integer is cast back to a 64-bit pointer
and dereferenced:

    qemu/slirp/tcp_input.c:
      207         ti = (struct tcpiphdr *) tp->seg_next;
      208         if (ti == (struct tcpiphdr *)tp || ti->ti_seq != tp->rcv_nxt)
      209                 return (0);

I believe the following patch should fix the problem:

===================== BEGIN kvm_tcp_seg_next.patch =====================
--- qemu/slirp/tcp_var.h.ORIG   2008-01-28 17:27:09.000000000 -0700
+++ qemu/slirp/tcp_var.h        2008-01-28 17:27:20.000000000 -0700
@@ -40,11 +40,7 @@
 #include "tcpip.h"
 #include "tcp_timer.h"

-#if SIZEOF_CHAR_P == 4
- typedef struct tcpiphdr *tcpiphdrp_32;
-#else
- typedef u_int32_t tcpiphdrp_32;
-#endif
+typedef struct tcpiphdr *tcpiphdrp_32;

 /*
  * Tcp control block, one per tcp; fields:
====================== END kvm_tcp_seg_next.patch ======================

As far as I can tell, tcpiphdr_32 is used only to define seg_next and
seg_prev so it _should_ be safe to define it as an ordinary pointer
regardless of 32/64-bitness.

There are a bunch of other potential sources of similar problems in
qemu/slirp, but I haven't yet triggered these:

    slirp/ip_input.c:278: warning: cast from pointer to integer of different size
    slirp/ip_input.c:298: warning: cast from pointer to integer of different size
    slirp/ip_input.c:427: warning: cast from pointer to integer of different size
    slirp/ip_input.c:429: warning: cast from pointer to integer of different size
    slirp/ip_input.c:430: warning: cast from pointer to integer of different size
    slirp/misc.c:115: warning: cast from pointer to integer of different size
    slirp/misc.c:116: warning: cast from pointer to integer of different size
    slirp/misc.c:118: warning: cast from pointer to integer of different size
    slirp/tcp_input.c:173: warning: cast from pointer to integer of different size

Still, you might want to have a look at those, too, to make sure that
KVM will work on large-memory machines.



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

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=893831&aid=1881532&group_id=180599

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

             reply	other threads:[~2008-01-29  1:16 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-01-29  1:16 SourceForge.net [this message]
  -- strict thread matches above, loose matches on Subject: below --
2008-07-07 10:28 [ kvm-Bugs-1881532 ] Network access seg faults KVM on large-memory machine SourceForge.net

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=E1JJf5M-00073D-LP@sc8-sf-web23.sourceforge.net \
    --to=noreply-pyega4qmqnroyomfzwx49a@public.gmane.org \
    --cc=kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox