From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1946814AbXBJLxo (ORCPT ); Sat, 10 Feb 2007 06:53:44 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S933441AbXBJLx2 (ORCPT ); Sat, 10 Feb 2007 06:53:28 -0500 Received: from cantor.suse.de ([195.135.220.2]:50377 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933430AbXBJLwm (ORCPT ); Sat, 10 Feb 2007 06:52:42 -0500 From: Andi Kleen References: <200702101252.033732000@suse.de> In-Reply-To: <200702101252.033732000@suse.de> To: Zachary Amsden , Andi Kleen , Jeremy Fitzhardinge , Rusty Russell , Chris Wright , patches@x86-64.org, linux-kernel@vger.kernel.org Subject: [PATCH 2.6.21 review II] [3/10] i386: iOPL handling for paravirt guests Message-Id: <20070210115231.2F26B13DD5@wotan.suse.de> Date: Sat, 10 Feb 2007 12:52:31 +0100 (CET) Sender: linux-kernel-owner@vger.kernel.org X-Mailing-List: linux-kernel@vger.kernel.org From: Zachary Amsden I found a clever way to make the extra IOPL switching invisible to non-paravirt compiles - since kernel_rpl is statically defined to be zero there, and only non-zero rpl kernel have a problem restoring IOPL, as popf does not restore IOPL flags unless run at CPL-0. Signed-off-by: Zachary Amsden Signed-off-by: Andi Kleen Cc: Andi Kleen Cc: Jeremy Fitzhardinge Cc: Rusty Russell Cc: Chris Wright Signed-off-by: Andrew Morton --- arch/i386/kernel/process.c | 9 +++++++++ 1 file changed, 9 insertions(+) Index: linux/arch/i386/kernel/process.c =================================================================== --- linux.orig/arch/i386/kernel/process.c +++ linux/arch/i386/kernel/process.c @@ -670,6 +670,15 @@ struct task_struct fastcall * __switch_t load_TLS(next, cpu); /* + * Restore IOPL if needed. In normal use, the flags restore + * in the switch assembly will handle this. But if the kernel + * is running virtualized at a non-zero CPL, the popf will + * not restore flags, so it must be done in a separate step. + */ + if (get_kernel_rpl() && unlikely(prev->iopl != next->iopl)) + set_iopl_mask(next->iopl); + + /* * Now maybe handle debug registers and/or IO bitmaps */ if (unlikely((task_thread_info(next_p)->flags & _TIF_WORK_CTXSW)