core: Preserve IF through call16()
authorH. Peter Anvin <hpa@zytor.com>
Mon, 21 Jun 2010 17:03:03 +0000 (10:03 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Mon, 21 Jun 2010 17:03:03 +0000 (10:03 -0700)
An intcall should always be invoked with interrupts off, but that is
not necessarily the case for a near or far call; in fact it is quite
the exception.  As such, do not filter IF in our register image, and
for our own internal call16() interface, propagate the protected-mode
IF value into real mode, just as we do for the pm_call interface.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
core/call16.c
core/callback.inc

index 86d7046..095f814 100644 (file)
@@ -1,6 +1,6 @@
 /* ----------------------------------------------------------------------- *
  *
- *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
  *
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
  */
 
 #include <stddef.h>
+#include <stdio.h>
 #include "core.h"
 
 const com32sys_t zero_regs;    /* Common all-zero register set */
 
+static inline uint32_t eflags(void)
+{
+    uint32_t v;
+
+    asm volatile("pushfl ; popl %0" : "=rm" (v));
+    return v;
+}
+
 void call16(void (*func)(void), const com32sys_t *ireg, com32sys_t *oreg)
 {
-    core_farcall((size_t)func, ireg, oreg);
+    com32sys_t xreg = *ireg;
+
+    /* Enable interrupts if and only if they are enabled in the caller */
+    xreg.eflags.l = (xreg.eflags.l & ~EFLAGS_IF) | (eflags() & EFLAGS_IF);
+
+    core_farcall((size_t)func, &xreg, oreg);
 }
index a33b582..6a35132 100644 (file)
@@ -74,7 +74,7 @@ core_syscall:
                mov eax,.rm_return      ; Return seg:offs
                stosd                   ; Save in stack frame
                mov eax,[edi-12]        ; Return flags
-               and eax,0x200cd7        ; Mask (potentially) unsafe flags
+               and eax,0x200ed7        ; Mask (potentially) unsafe flags
                mov [edi-12],eax        ; Primary flags entry
                stosw                   ; Return flags