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 ([EMAIL PROTECTED]) (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 ([EMAIL PROTECTED]) (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/ _______________________________________________ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel