From: Ben Hutchings <ben@decadent.org.uk>
To: x86@kernel.org
Cc: linux-kernel@vger.kernel.org, Richard Kettlewell <rjk@terraraq.org.uk>
Subject: [PATCH] x86: Fix code patching for paravirt-alternatives on 486
Date: Wed, 09 Sep 2009 00:23:48 +0100 [thread overview]
Message-ID: <1252452228.3423.121.camel@localhost> (raw)
[-- Attachment #1: Type: text/plain, Size: 2516 bytes --]
As reported in <http://bugs.debian.org/511703> and
<http://bugs.debian.org/515982>, kernels with paravirt-alternatives
enabled crash in text_poke_early() on at least some 486-class
processors.
The problem is that text_poke_early() itself contains paravirt-
alternatives and therefore will modify instructions that have already
been prefetched. Pentium and later processors will invalidate the
prefetched instructions in this case, but 486-class processors do
not. We must use a jmp instruction to limit prefetching.
There is then a further problem in that sync_core() uses "cpuid" which
isn't implemented by most 486-class processors. Since they also do
not perform speculative execution, we can make this conditional on the
processor family.
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
This has been tested as a change to 2.6.26 by Richard Kettlewell. This
code doesn't appear to have changed significantly since then, so
hopefully the change is still correct.
Possible the call to sync_core() should be moved above the
local_irq_restore() and should incorporate the dummy jmp?
Ben.
arch/x86/include/asm/processor.h | 6 ++++++
arch/x86/kernel/alternative.c | 3 +++
2 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index c776826..74ddfce 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -708,6 +708,12 @@ static inline void sync_core(void)
{
int tmp;
+#if defined(CONFIG_M386) || defined(CONFIG_M486)
+ /* This is unnecessary on 386- and 486-class processors, most of
+ which don't even implement CPUID. */
+ if (boot_cpu_data.x86 < 5)
+ return;
+#endif
asm volatile("cpuid" : "=a" (tmp) : "0" (1)
: "ebx", "ecx", "edx", "memory");
}
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index 4869351..330ab89 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -498,6 +498,9 @@ static void *__init_or_module text_poke_early(void *addr, const void *opcode,
unsigned long flags;
local_irq_save(flags);
memcpy(addr, opcode, len);
+ /* Force 486-class processors to flush prefetched instructions,
+ since we may have just patched local_irq_restore(). */
+ asm volatile("jmp 1f\n1:\n" ::: "memory");
local_irq_restore(flags);
sync_core();
/* Could also do a CLFLUSH here to speed up CPU recovery; but
--
1.6.3.3
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]
next reply other threads:[~2009-09-08 23:23 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-09-08 23:23 Ben Hutchings [this message]
2009-09-09 0:31 ` [PATCH] x86: Fix code patching for paravirt-alternatives on 486 H. Peter Anvin
2009-09-09 0:46 ` Ben Hutchings
2009-09-09 1:00 ` H. Peter Anvin
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=1252452228.3423.121.camel@localhost \
--to=ben@decadent.org.uk \
--cc=linux-kernel@vger.kernel.org \
--cc=rjk@terraraq.org.uk \
--cc=x86@kernel.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