[patch 8/9] F00F bug fixup for i386 - use conditional calls

Mathieu Desnoyers
2007-05-30T14:04:43Z

[-- Attachment #1: f00f-bug-use-cond-calls.patch --]
[-- Type: text/plain, Size: 2891 bytes --]

Use the faster conditional calls for F00F bug handling in do_page_fault.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>

---
arch/i386/Kconfig.cpu | 1 +
arch/i386/kernel/traps.c | 2 ++
arch/i386/mm/fault.c | 35 ++++++++++++++++++++++-------------
3 files changed, 25 insertions(+), 13 deletions(-)

Index: linux-2.6-lttng/arch/i386/kernel/traps.c
===================================================================
--- linux-2.6-lttng.orig/arch/i386/kernel/traps.c 2007-05-29 11:05:30.000000000 -0400
+++ linux-2.6-lttng/arch/i386/kernel/traps.c 2007-05-29 11:07:07.000000000 -0400
@@ -31,6 +31,7 @@
#include <linux/uaccess.h>
#include <linux/nmi.h>
#include <linux/bug.h>
+#include <linux/condcall.h>

#ifdef CONFIG_EISA
#include <linux/ioport.h>
@@ -1084,6 +1085,7 @@
*/
idt_descr.address = fix_to_virt(FIX_F00F_IDT);
load_idt(&idt_descr);
+ BUG_ON(cond_call_arm("fix_f00f"));
}
#endif

Index: linux-2.6-lttng/arch/i386/mm/fault.c
===================================================================
--- linux-2.6-lttng.orig/arch/i386/mm/fault.c 2007-05-29 11:05:48.000000000 -0400
+++ linux-2.6-lttng/arch/i386/mm/fault.c 2007-05-29 11:13:16.000000000 -0400
@@ -25,6 +25,7 @@
#include <linux/kprobes.h>
#include <linux/uaccess.h>
#include <linux/kdebug.h>
+#include <linux/condcall.h>

#include <asm/system.h>
#include <asm/desc.h>
@@ -221,6 +222,25 @@

fastcall void do_invalid_op(struct pt_regs *, unsigned long);

+#ifdef CONFIG_X86_F00F_BUG
+/*
+ * Pentium F0 0F C7 C8 bug workaround.
+ */
+static inline int do_f00f_workaround(struct pt_regs *regs,
+ unsigned long address)
+{
+ unsigned long nr;
+
+ nr = (address - idt_descr.address) >> 3;
+
+ if (nr == 6) {
+ do_invalid_op(regs, 0);
+ return 1;
+ }
+ return 0;
+}
+#endif
+
static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
{
unsigned index = pgd_index(address);
@@ -474,19 +494,8 @@
}

#ifdef CONFIG_X86_F00F_BUG
- /*
- * Pentium F0 0F C7 C8 bug workaround.
- */
- if (boot_cpu_data.f00f_bug) {
- unsigned long nr;
-
- nr = (address - idt_descr.address) >> 3;
-
- if (nr == 6) {
- do_invalid_op(regs, 0);
- return;
- }
- }
+ if (cond_call(fix_f00f, do_f00f_workaround(regs, address)))
+ return;
#endif

no_context:
Index: linux-2.6-lttng/arch/i386/Kconfig.cpu
===================================================================
--- linux-2.6-lttng.orig/arch/i386/Kconfig.cpu 2007-05-29 11:51:46.000000000 -0400
+++ linux-2.6-lttng/arch/i386/Kconfig.cpu 2007-05-29 11:52:08.000000000 -0400
@@ -275,6 +275,7 @@
config X86_F00F_BUG
bool
depends on M586MMX || M586TSC || M586 || M486 || M386
+ select COND_CALL
default y

config X86_WP_WORKS_OK