From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by monty-python.gnu.org with tmda-scanned (Exim 4.24) id 1AkOXJ-0008Om-Fo for qemu-devel@nongnu.org; Sat, 24 Jan 2004 09:13:21 -0500 Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.24) id 1AkOWn-0008Jb-N9 for qemu-devel@nongnu.org; Sat, 24 Jan 2004 09:13:20 -0500 Received: from [66.70.73.150] (helo=lists.samba.org) by monty-python.gnu.org with esmtp (Exim 4.24) id 1AkOWn-0008JI-De for qemu-devel@nongnu.org; Sat, 24 Jan 2004 09:12:49 -0500 From: Rusty Russell Date: Sun, 25 Jan 2004 01:09:52 +1100 Sender: rusty@bach.samba.org Message-Id: <20040124141301.4C5EE2C016@lists.samba.org> Subject: [Qemu-devel] qemu 0.5.1 emulation bug? Reply-To: qemu-devel@nongnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Fabrice Bellard Cc: qemu-devel@nongnu.org Just spent two hours chasing down why recent 2.6.2-rc1 kernels don't boot. It turns out that find_next_bit() returns 0 under "qemu-fast" and "qemu" where it returns 32 under "qemu-i386" and native x86. Bedtime for me, but here's the offending code: /** * find_first_bit - find the first set bit in a memory region * @addr: The address to start the search at * @size: The maximum size to search * * Returns the bit-number of the first set bit, not the number of the byte * containing a bit. */ static __inline__ int xfind_first_bit(const unsigned long *addr, unsigned size) { int d0, d1; int res; /* This looks at memory. Mark it volatile to tell gcc not to move it around */ __asm__ __volatile__( "xorl %%eax,%%eax\n\t" "repe; scasl\n\t" "jz 1f\n\t" "leal -4(%%edi),%%edi\n\t" "bsfl (%%edi),%%eax\n" "1:\tsubl %%ebx,%%edi\n\t" "shll $3,%%edi\n\t" "addl %%edi,%%eax" :"=a" (res), "=&c" (d0), "=&D" (d1) :"1" ((size + 31) >> 5), "2" (addr), "b" (addr)); return res; } /** * find_next_bit - find the first set bit in a memory region * @addr: The address to base the search on * @offset: The bitnumber to start searching at * @size: The maximum size to search */ static __inline__ int xfind_next_bit(const unsigned long *addr, int size, int offset) { const unsigned long *p = addr + (offset >> 5); int set = 0, bit = offset & 31, res; if (bit) { /* * Look for nonzero in the first 32 bits: */ __asm__("bsfl %1,%0\n\t" "jne 1f\n\t" "movl $32, %0\n" "1:" : "=r" (set) : "r" (*p >> bit)); if (set < (32 - bit)) return set + offset; set = 32 - bit; p++; } /* * No set bit yet, search remaining full words for a bit */ res = xfind_first_bit (p, size - 32 * (p - addr)); return (offset + set + res); } int main() { unsigned long map = 1; printf("find_next_bit of %lu = %i\n", map, xfind_next_bit(&map, 32, 1)); return 0; } -- Anyone who quotes me in their sig is an idiot. -- Rusty Russell.