qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Bernhard Kauer <kauer@os.inf.tu-dresden.de>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] Patch: generate double and triple faults
Date: Sat, 31 Mar 2007 14:14:57 +0200	[thread overview]
Message-ID: <20070331121457.GG24080@silo.inf.tu-dresden.de> (raw)
In-Reply-To: <20070328123931.GA24080@silo.inf.tu-dresden.de>

[-- Attachment #1: Type: text/plain, Size: 885 bytes --]

On Wed, Mar 28, 2007 at 02:39:31PM +0200, Bernhard Kauer wrote:
> On Wed, Mar 28, 2007 at 10:13:49AM +0200, Sebastian Kaliszewski wrote:
> > Bernhard Kauer wrote:
> > >Qemu does not generate a double fault (DBF) on x86, if a general protection
> > >fault could not be delivered. Instead it hangs in a loop.
> > >
> > >The patch fix this bug by checking whether we are already in a GPF 
> > >exception.
> > 
> > If you're at it, maybe add triple fault handling (ie exception if DBF 
> > handler) -- it should reset CPU.
> 
> There are many things missing in the x86 exception handling. For example
> the case PF -> PF is also not handled.

The attached patch implements double andd triple fault handling and makes
the last patch obsolete. It does not generate a reset on triple fault, but
it aborts qemu. The same happen currently if the TSS is bogous.


Greetings,

    Bernhard Kauer

[-- Attachment #2: qemu_exceptions.diff --]
[-- Type: text/plain, Size: 3227 bytes --]

Index: cpu-exec.c
===================================================================
RCS file: /sources/qemu/qemu/cpu-exec.c,v
retrieving revision 1.97
diff -u -r1.97 cpu-exec.c
--- cpu-exec.c	30 Mar 2007 16:44:53 -0000	1.97
+++ cpu-exec.c	31 Mar 2007 11:59:52 -0000
@@ -360,6 +360,7 @@
                                  env->exception_is_int, 
                                  env->error_code, 
                                  env->exception_next_eip, 0);
+		    env->old_exception = -1;  // successful delivered
 #elif defined(TARGET_PPC)
                     do_interrupt(env);
 #elif defined(TARGET_MIPS)
Index: target-i386/helper.c
===================================================================
RCS file: /sources/qemu/qemu/target-i386/helper.c,v
retrieving revision 1.74
diff -u -r1.74 helper.c
--- target-i386/helper.c	1 Feb 2007 22:12:19 -0000	1.74
+++ target-i386/helper.c	31 Mar 2007 11:59:58 -0000
@@ -1192,6 +1193,37 @@
     }
 }
 
+
+/**
+ * Check nested exceptions and change to double or triple fault if
+ * needed. It should only be called, if this is not an
+ * interrrupt. Returns the new exception number.
+ */
+int check_exception(int intno, int *error_code)
+{
+  if (loglevel & CPU_LOG_INT)
+    fprintf(logfile, "%s()  old: %x new %x\n",__func__,  env->old_exception, intno);
+
+
+ if (env->old_exception == EXCP08_DBLE)
+   cpu_abort(env, "triple fault");
+
+ char  first_contributory  = env->old_exception == 0 || (env->old_exception >= 10 && env->old_exception <= 13);
+ char second_contributory  = intno == 0 || (intno >= 10 && intno <= 13);
+
+ if ((first_contributory && second_contributory) 
+     || (env->old_exception == EXCP0E_PAGE && (second_contributory || (intno == EXCP0E_PAGE))))
+   {
+     intno = EXCP08_DBLE;
+     *error_code = 0;
+   }
+
+ if (second_contributory || (intno == EXCP0E_PAGE) || (intno == EXCP08_DBLE))
+   env->old_exception = intno;
+ return intno;
+}
+
+
 /*
  * Signal an interruption. It is executed in the main CPU loop.
  * is_int is TRUE if coming from the int instruction. next_eip is the
@@ -1201,6 +1233,9 @@
 void raise_interrupt(int intno, int is_int, int error_code, 
                      int next_eip_addend)
 {
+    if (!is_int)
+        intno = check_exception(intno, &error_code);
+
     env->exception_index = intno;
     env->error_code = error_code;
     env->exception_is_int = is_int;
@@ -1211,6 +1246,8 @@
 /* same as raise_exception_err, but do not restore global registers */
 static void raise_exception_err_norestore(int exception_index, int error_code)
 {
+    exception_index = check_exception(exception_index, &error_code);
+
     env->exception_index = exception_index;
     env->error_code = error_code;
     env->exception_is_int = 0;
Index: target-i386/cpu.h
===================================================================
RCS file: /sources/qemu/qemu/target-i386/cpu.h,v
retrieving revision 1.41
diff -u -r1.41 cpu.h
--- target-i386/cpu.h	5 Feb 2007 22:06:27 -0000	1.41
+++ target-i386/cpu.h	31 Mar 2007 11:59:56 -0000
@@ -515,6 +515,7 @@
     uint32_t smbase;
     int interrupt_request; 
     int user_mode_only; /* user mode only simulation */
+    int old_exception;  /* exception in flight */
 
     CPU_COMMON
 

      reply	other threads:[~2007-03-31 12:17 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-03-27 11:40 [Qemu-devel] Patch: generate a DBF when a GPF could not be delivered on x86 Bernhard Kauer
2007-03-28  8:13 ` Sebastian Kaliszewski
2007-03-28 12:39   ` Bernhard Kauer
2007-03-31 12:14     ` Bernhard Kauer [this message]

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=20070331121457.GG24080@silo.inf.tu-dresden.de \
    --to=kauer@os.inf.tu-dresden.de \
    --cc=qemu-devel@nongnu.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;
as well as URLs for NNTP newsgroup(s).