From 4e7d836b8cdc0e785ac6e0a78b258c4e193d2222 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Mon, 21 Jun 2010 10:03:03 -0700 Subject: [PATCH] core: Preserve IF through call16() 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 --- core/call16.c | 18 ++++++++++++++++-- core/callback.inc | 2 +- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/core/call16.c b/core/call16.c index 86d7046..095f814 100644 --- a/core/call16.c +++ b/core/call16.c @@ -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 @@ -17,11 +17,25 @@ */ #include +#include #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); } diff --git a/core/callback.inc b/core/callback.inc index a33b582..6a35132 100644 --- a/core/callback.inc +++ b/core/callback.inc @@ -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 -- 2.7.4