From: Luca Barbieri <luca@luca-barbieri.com>
To: mingo@elte.hu
Cc: hpa@zytor.com, a.p.zijlstra@chello.nl, akpm@linux-foundation.org,
linux-kernel@vger.kernel.org,
Luca Barbieri <luca@luca-barbieri.com>
Subject: [PATCH 1/5] x86: add support for relative CALL and JMP in alternatives (v2)
Date: Fri, 19 Feb 2010 18:26:40 +0100 [thread overview]
Message-ID: <1266600404-16402-2-git-send-email-luca@luca-barbieri.com> (raw)
In-Reply-To: <1266600404-16402-1-git-send-email-luca@luca-barbieri.com>
Changes in v2:
- Don't use instruction parser: use the method described below instead
Currently CALL and JMP cannot be used in alternatives because the
relative offset would be wrong.
This patch adds a new type of alternative, denoted by replacementlen = 0xff.
This alternative causes the kernel to generate a CALL rel32 to the
address provided in the alternative sequence address field.
This can be generated with ALTERNATIVE_CALL
This approach has the advantage of not requiring the instruction parser,
not requiring ad-hoc compile time relocation logic, and minimizing the
size of the alternative data.
Alternatives more complex than a single CALL could still be supported
with multiple successive alternative patches, but this is currently not
required.
Signed-off-by: Luca Barbieri <luca@luca-barbieri.com>
---
arch/x86/include/asm/alternative.h | 14 ++++++++++++++
arch/x86/kernel/alternative.c | 24 ++++++++++++++++++++----
2 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h
index 69b74a7..77f78e2 100644
--- a/arch/x86/include/asm/alternative.h
+++ b/arch/x86/include/asm/alternative.h
@@ -90,6 +90,20 @@ static inline void alternatives_smp_switch(int smp) {}
"663:\n\t" newinstr "\n664:\n" /* replacement */ \
".previous"
+#define ALTERNATIVE_CALL(oldinstr, func, feature) \
+ \
+ "661:\n\t" oldinstr "\n662:\n" \
+ ".section .altinstructions,\"a\"\n" \
+ _ASM_ALIGN "\n" \
+ _ASM_PTR "661b\n" /* label */ \
+ _ASM_PTR func "\n" /* new instruction */ \
+ " .byte " __stringify(feature) "\n" /* feature bit */ \
+ " .byte 662b-661b\n" /* sourcelen */ \
+ " .byte 0xff\n" /* replacementlen */ \
+ " .byte 0\n" /* pad */ \
+ ".previous\n" \
+
+
/*
* Alternative instructions for different CPU types or capabilities.
*
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index de7353c..77eba91 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -210,7 +210,7 @@ void __init_or_module apply_alternatives(struct alt_instr *start,
DPRINTK("%s: alt table %p -> %p\n", __func__, start, end);
for (a = start; a < end; a++) {
u8 *instr = a->instr;
- BUG_ON(a->replacementlen > a->instrlen);
+ size_t len;
BUG_ON(a->instrlen > sizeof(insnbuf));
if (!boot_cpu_has(a->cpuid))
continue;
@@ -222,9 +222,25 @@ void __init_or_module apply_alternatives(struct alt_instr *start,
__func__, a->instr, instr);
}
#endif
- memcpy(insnbuf, a->replacement, a->replacementlen);
- add_nops(insnbuf + a->replacementlen,
- a->instrlen - a->replacementlen);
+ if (a->replacementlen == 0xff) {
+ /* emit a CALL rel32 */
+ long v = a->replacement - (instr + 5);
+ int v32 = (int)v;
+ BUG_ON(5 > a->instrlen);
+#ifdef CONFIG_X86_64
+ if (WARN_ON((long)v32 != v))
+ continue;
+#endif
+ len = 5;
+ insnbuf[0] = 0xe8;
+ memcpy(insnbuf + 1, &v32, 4);
+ } else {
+ BUG_ON(a->replacementlen > a->instrlen);
+ len = a->replacementlen;
+ memcpy(insnbuf, a->replacement, len);
+ }
+ add_nops(insnbuf + len,
+ a->instrlen - len);
text_poke_early(instr, insnbuf, a->instrlen);
}
}
--
1.6.6.1.476.g01ddb
next prev parent reply other threads:[~2010-02-19 17:27 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-02-19 17:26 [PATCH 0/5] x86-32: improve atomic64_t functions (v2) Luca Barbieri
2010-02-19 17:26 ` Luca Barbieri [this message]
2010-02-19 17:26 ` [PATCH 2/5] x86: add support for lock prefix in alternatives (v2) Luca Barbieri
2010-02-19 17:26 ` [PATCH 3/5] x86-32: allow UP/SMP lock replacement in cmpxchg64 (v2) Luca Barbieri
2010-02-19 17:26 ` [PATCH 4/5] lib: add self-test for atomic64_t Luca Barbieri
2010-02-19 17:26 ` [PATCH 5/5] x86-32: rewrite 32-bit atomic64 functions in assembly (v2) Luca Barbieri
2010-02-23 22:47 ` [PATCH 0/5] x86-32: improve atomic64_t functions (v2) H. Peter Anvin
2010-02-24 9:56 ` Luca Barbieri
2010-02-26 10:14 ` Ingo Molnar
2010-02-26 11:08 ` Luca Barbieri
2010-02-26 11:23 ` Luca Barbieri
2010-03-01 7:35 ` H. Peter Anvin
2010-03-01 8:49 ` Paul Mackerras
2010-03-01 17:16 ` Luca Barbieri
2010-03-01 17:31 ` Luca Barbieri
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=1266600404-16402-2-git-send-email-luca@luca-barbieri.com \
--to=luca@luca-barbieri.com \
--cc=a.p.zijlstra@chello.nl \
--cc=akpm@linux-foundation.org \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
/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
all inboxes | Powered by JetHome®