[PATCH 01/10] x86: add support for multiple choice alternatives

From: Luca Barbieri
Date: Wed Feb 17 2010 - 06:43:09 EST


This patch modifies the x86 alternative macros to allow more than one
alternative code sequence.

This is done by simply adding multiple alternative patches, which are
applied in sequence, overwriting previous ones.

Signed-off-by: Luca Barbieri <luca@xxxxxxxxxxxxxxxxx>
---
arch/x86/include/asm/alternative.h | 27 ++++++++++++++++++++-------
1 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/arch/x86/include/asm/alternative.h b/arch/x86/include/asm/alternative.h
index 69b74a7..42d41ac 100644
--- a/arch/x86/include/asm/alternative.h
+++ b/arch/x86/include/asm/alternative.h
@@ -73,23 +73,36 @@ static inline void alternatives_smp_module_del(struct module *mod) {}
static inline void alternatives_smp_switch(int smp) {}
#endif /* CONFIG_SMP */

-/* alternative assembly primitive: */
-#define ALTERNATIVE(oldinstr, newinstr, feature) \
- \
- "661:\n\t" oldinstr "\n662:\n" \
+#define ALTERNATIVE_PATCH(oldstart, oldend, newinstr, feature) \
".section .altinstructions,\"a\"\n" \
_ASM_ALIGN "\n" \
- _ASM_PTR "661b\n" /* label */ \
+ _ASM_PTR oldstart "\n" /* label */ \
_ASM_PTR "663f\n" /* new instruction */ \
" .byte " __stringify(feature) "\n" /* feature bit */ \
- " .byte 662b-661b\n" /* sourcelen */ \
+ " .byte (" oldend ")-(" oldstart ")\n" /* sourcelen */ \
" .byte 664f-663f\n" /* replacementlen */ \
- " .byte 0xff + (664f-663f) - (662b-661b)\n" /* rlen <= slen */ \
+ " .byte 0xff + (664f-663f) - ((" oldend ")-(" oldstart "))\n" /* rlen <= slen */ \
".previous\n" \
".section .altinstr_replacement, \"ax\"\n" \
"663:\n\t" newinstr "\n664:\n" /* replacement */ \
".previous"

+/* alternative assembly primitive: */
+#define ALTERNATIVE(oldinstr, newinstr, feature) \
+ "661:\n\t" oldinstr "\n662:\n" \
+ ALTERNATIVE_PATCH("661b", "662b", newinstr, feature)
+
+#define ALTERNATIVE3(oldinstr, newinstr1, feature1, newinstr2, feature2) \
+ "661:\n\t" oldinstr "\n662:\n" \
+ ALTERNATIVE_PATCH("661b", "662b", newinstr1, feature1) "\n" \
+ ALTERNATIVE_PATCH("661b", "662b", newinstr2, feature2)
+
+#define ALTERNATIVE4(oldinstr, newinstr1, feature1, newinstr2, feature2, newinstr3, feature3) \
+ "661:\n\t" oldinstr "\n662:\n" \
+ ALTERNATIVE_PATCH("661b", "662b", newinstr1, feature1) "\n" \
+ ALTERNATIVE_PATCH("661b", "662b", newinstr2, feature2) "\n" \
+ ALTERNATIVE_PATCH("661b", "662b", newinstr3, feature3)
+
/*
* Alternative instructions for different CPU types or capabilities.
*
--
1.6.6.1.476.g01ddb

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/