lkml.org 
[lkml]   [2010]   [Feb]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH 01/10] x86: add support for multiple choice alternatives
Date
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@luca-barbieri.com>
---
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


\
 
 \ /
  Last update: 2010-02-17 12:45    [from the cache]
©2003-2011 Jasper Spaans