From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1K5sGl-00023s-94 for qemu-devel@nongnu.org; Mon, 09 Jun 2008 21:03:27 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1K5sGj-00021X-ES for qemu-devel@nongnu.org; Mon, 09 Jun 2008 21:03:26 -0400 Received: from [199.232.76.173] (port=54732 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1K5sGj-00021K-Ak for qemu-devel@nongnu.org; Mon, 09 Jun 2008 21:03:25 -0400 Received: from outgoing.csail.mit.edu ([128.30.2.149]:45086) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1K5sGi-0004Sc-Tf for qemu-devel@nongnu.org; Mon, 09 Jun 2008 21:03:24 -0400 Received: from uncle-of-god.csail.mit.edu ([128.30.64.171]) by outgoing.csail.mit.edu with esmtps (TLSv1:AES256-SHA:256) (Exim 4.63) (envelope-from ) id 1K5sGg-0008OD-MJ for qemu-devel@nongnu.org; Mon, 09 Jun 2008 21:03:22 -0400 Received: from wentzlaf (helo=localhost) by uncle-of-god.csail.mit.edu with local-esmtp (Exim 4.63) (envelope-from ) id 1K5sGg-0005Cx-JO for qemu-devel@nongnu.org; Mon, 09 Jun 2008 21:03:22 -0400 Date: Mon, 9 Jun 2008 21:03:22 -0400 (EDT) From: David Wentzlaff Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed Sender: David Wentzlaff Subject: [Qemu-devel] [PATCH] x86_64 Exception hardware checks incorrect bits of IDT entry Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org When using an x86_64 client on QEMU, the function do_interrupt64 in target-i386/op_helper.c (used to be called target-i386/helper.c) checks bits in an IDT entry as if it was a segment descriptor. IDT entries are not segment descriptors (but are similar) and it looks like this might have been a copy and paste error from segment descriptor check logic. Namely do_interrupt64 checks DESC_S_MASK, DESC_CS_MASK, DESC_L_MASK, DESC_B_MASK, and DESC_C_MASK all of which are either in the Offset [31:16] field of a 64-bit IDT entry or it checks bits which are in the second word, but are used for the type of the IDT (whether it is a trap gate vs interrupt gate). When these bits are not set appropriately, QEMU x86_64 erroneously throws a GPF. I am not sure how QEMU is capable of booting any x86_64 operating system problem. The only thing I can think of is that there was some very fortuitous alignment of common x86_64 OS's interrupt vectors... Please check and review this change. The IDT entry format on x86_64 can examined in Intel's x86 Software Developers Manual Volume 3A page 5-23 figure 5-7. The patch simply removes these erroneous checks and is below (note that this diff is against the main trunk, but this problem existed in the last release (0.9.1) also, but there it was in a file called target-i386/helper.c. Sincerely, David Wentzlaff ----- Patch starts here ----- Index: target-i386/op_helper.c =================================================================== --- target-i386/op_helper.c (revision 4716) +++ target-i386/op_helper.c (working copy) @@ -914,16 +914,12 @@ if (load_segment(&e1, &e2, selector) != 0) raise_exception_err(EXCP0D_GPF, selector & 0xfffc); - if (!(e2 & DESC_S_MASK) || !(e2 & (DESC_CS_MASK))) - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); dpl = (e2 >> DESC_DPL_SHIFT) & 3; if (dpl > cpl) raise_exception_err(EXCP0D_GPF, selector & 0xfffc); if (!(e2 & DESC_P_MASK)) raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc); - if (!(e2 & DESC_L_MASK) || (e2 & DESC_B_MASK)) - raise_exception_err(EXCP0D_GPF, selector & 0xfffc); - if ((!(e2 & DESC_C_MASK) && dpl < cpl) || ist != 0) { + if ((dpl < cpl) || ist != 0) { /* to inner privilege */ if (ist != 0) esp = get_rsp_from_tss(ist + 3); @@ -932,7 +928,7 @@ esp &= ~0xfLL; /* align stack */ ss = 0; new_stack = 1; - } else if ((e2 & DESC_C_MASK) || dpl == cpl) { + } else if (dpl == cpl) { /* to same privilege */ if (env->eflags & VM_MASK) raise_exception_err(EXCP0D_GPF, selector & 0xfffc);