From: "Joerg Roedel" <joerg.roedel@amd.com>
To: discuss@x86-64.org
Cc: "Andi Kleen" <ak@suse.de>, linux-kernel@vger.kernel.org
Subject: [PATCH 1/4] i386: extend alternative instructions framework
Date: Wed, 28 Feb 2007 15:14:24 +0100 [thread overview]
Message-ID: <20070228141424.GB19452@amd.com> (raw)
In-Reply-To: <20070228140501.GA19452@amd.com>
[-- Attachment #1: Type: text/plain, Size: 267 bytes --]
From: Joerg Roedel <joerg.roedel@amd.com>
This patch extends the alternative instructions framework to support 2
alternative instructions.
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
--
Joerg Roedel
Operating System Research Center
AMD Saxony LLC & Co. KG
[-- Attachment #2: two-alternatives-i386.patch --]
[-- Type: text/plain, Size: 5024 bytes --]
diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c
index 9eca21b..59f1770 100644
--- a/arch/i386/kernel/alternative.c
+++ b/arch/i386/kernel/alternative.c
@@ -153,14 +153,23 @@ extern u8 __smp_alt_begin[], __smp_alt_end[];
void apply_alternatives(struct alt_instr *start, struct alt_instr *end)
{
struct alt_instr *a;
- u8 *instr;
+ u8 *instr, *replacement;
+ u8 replacementlen;
int diff;
DPRINTK("%s: alt table %p -> %p\n", __FUNCTION__, start, end);
for (a = start; a < end; a++) {
- BUG_ON(a->replacementlen > a->instrlen);
- if (!boot_cpu_has(a->cpuid))
+ if (boot_cpu_has(a->cpuid)) {
+ replacement = a->replacement;
+ replacementlen = a->replacementlen;
+ } else if ((a->replacementlen2 > 0) &&
+ (boot_cpu_has(a->cpuid2))) {
+ replacement = a->replacement2;
+ replacementlen = a->replacementlen2;
+ } else
continue;
+
+ BUG_ON(replacementlen > a->instrlen);
instr = a->instr;
#ifdef CONFIG_X86_64
/* vsyscall code is not mapped yet. resolve it manually. */
@@ -170,9 +179,9 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end)
__FUNCTION__, a->instr, instr);
}
#endif
- memcpy(instr, a->replacement, a->replacementlen);
- diff = a->instrlen - a->replacementlen;
- nop_out(instr + a->replacementlen, diff);
+ memcpy(instr, replacement, replacementlen);
+ diff = a->instrlen - replacementlen;
+ nop_out(instr + replacementlen, diff);
}
}
diff --git a/include/asm-i386/alternative.h b/include/asm-i386/alternative.h
index b8fa955..4a77e93 100644
--- a/include/asm-i386/alternative.h
+++ b/include/asm-i386/alternative.h
@@ -10,11 +10,14 @@
struct alt_instr {
u8 *instr; /* original instruction */
u8 *replacement;
+ u8 *replacement2;
u8 cpuid; /* cpuid bit set for replacement */
+ u8 cpuid2; /* cpuid bit set for replacement2 */
u8 instrlen; /* length of original instruction */
u8 replacementlen; /* length of new instruction, <= instrlen */
- u8 pad;
-};
+ u8 replacementlen2;
+ u8 pad[3];
+} __attribute__ ((packed));
extern void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
@@ -36,6 +39,12 @@ static inline void alternatives_smp_switch(int smp) {}
#endif
/*
+ * use this macro(s) if you need more than one output parameter
+ * in alternative_io_*
+ */
+#define ASM_OUTPUT2(a, b) a, b
+
+/*
* Alternative instructions for different CPU types or capabilities.
*
* This allows to use optimized instructions even on generic binary
@@ -53,9 +62,12 @@ static inline void alternatives_smp_switch(int smp) {}
" .align 4\n" \
" .long 661b\n" /* label */ \
" .long 663f\n" /* new instruction */ \
+ " .long 0x00\n" \
" .byte %c0\n" /* feature bit */ \
+ " .byte 0x00\n" \
" .byte 662b-661b\n" /* sourcelen */ \
" .byte 664f-663f\n" /* replacementlen */ \
+ " .byte 0x00\n" \
".previous\n" \
".section .altinstr_replacement,\"ax\"\n" \
"663:\n\t" newinstr "\n664:\n" /* replacement */\
@@ -77,14 +89,38 @@ static inline void alternatives_smp_switch(int smp) {}
" .align 4\n" \
" .long 661b\n" /* label */ \
" .long 663f\n" /* new instruction */ \
+ " .long 0x00\n" \
" .byte %c0\n" /* feature bit */ \
+ " .byte 0x00\n" \
" .byte 662b-661b\n" /* sourcelen */ \
" .byte 664f-663f\n" /* replacementlen */ \
+ " .byte 0x00\n" \
".previous\n" \
".section .altinstr_replacement,\"ax\"\n" \
"663:\n\t" newinstr "\n664:\n" /* replacement */\
".previous" :: "i" (feature), ##input)
+/* Like alternative_io, but supports 2 possible alternatives */
+#define alternative_io_two(oldinstr, newinstr, feat, newinstr2, feat2,\
+ output, input...) \
+ asm volatile ("661:\n\t" oldinstr "\n662:\n" \
+ ".section .altinstructions,\"a\"\n" \
+ " .align 4\n" \
+ " .long 661b\n" /* label */ \
+ " .long 663f\n" /* new instruction */ \
+ " .long 665f\n" /* new instruction 2 */\
+ " .byte %c[f]\n" /* feature bit */ \
+ " .byte %c[f2]\n" /* feature bit 2*/ \
+ " .byte 662b-661b\n" /* sourcelen */ \
+ " .byte 664f-663f\n" /* replacementlen */ \
+ " .byte 666f-665f\n" /* replacementlen 2 */\
+ ".previous\n" \
+ ".section .altinstr_replacement,\"ax\"\n" \
+ "663:\n\t" newinstr "\n664:\n" /* replacement */ \
+ "665:\n\t" newinstr2 "\n666:\n" /* replacement2 */ \
+ ".previous" : output : [f] "i" (feat), \
+ [f2] "i" (feat2),##input)
+
/*
* Alternative inline assembly for SMP.
*
next prev parent reply other threads:[~2007-02-28 14:14 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-02-28 14:05 [PATCH 0/4] improve alternative instruction code and optimize get_cycles_sync Joerg Roedel
2007-02-28 14:14 ` Joerg Roedel [this message]
2007-02-28 14:18 ` [PATCH 2/4] x86_64: changes to x86_64 architecture for alternative instruction improvements Joerg Roedel
2007-02-28 14:21 ` [PATCH 3/4] i386: add the X86_FEATURE_SYNC_RDTSC flag Joerg Roedel
2007-02-28 14:25 ` [PATCH 4/4] optimize and simplify get_cycles_sync() Joerg Roedel
2007-03-07 0:25 ` Andrew Morton
2007-03-09 9:57 ` Joerg Roedel
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=20070228141424.GB19452@amd.com \
--to=joerg.roedel@amd.com \
--cc=ak@suse.de \
--cc=discuss@x86-64.org \
--cc=linux-kernel@vger.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.