[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen master] x86: support 2- and 3-way alternatives



commit 6f8e41c67a884b5eaa321bd58fdcf593179f5f2c
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Thu Feb 4 11:38:52 2016 +0100
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Thu Feb 4 11:38:52 2016 +0100

    x86: support 2- and 3-way alternatives
    
    Parts taken from Linux, but implementing the ALTERNATIVE*() macros
    recursively to avoid needless redundancy.
    
    Also make the .discard section non-writable (we might even consider
    dropping its alloc flag too) and limit the pushing and popping of
    sections.
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
---
 xen/include/asm-x86/alternative.h | 63 ++++++++++++++++++++++++++++++++-------
 1 file changed, 52 insertions(+), 11 deletions(-)

diff --git a/xen/include/asm-x86/alternative.h 
b/xen/include/asm-x86/alternative.h
index 7d11354..1056630 100644
--- a/xen/include/asm-x86/alternative.h
+++ b/xen/include/asm-x86/alternative.h
@@ -46,18 +46,28 @@ extern void alternative_instructions(void);
 #define ALTINSTR_REPLACEMENT(newinstr, feature, number) /* replacement */     \
         b_replacement(number)":\n\t" newinstr "\n" e_replacement(number) 
":\n\t"
 
+#define ALTERNATIVE_N(newinstr, feature, number)       \
+       ".pushsection .altinstructions,\"a\"\n"         \
+       ALTINSTR_ENTRY(feature, number)                 \
+       ".section .discard,\"a\",@progbits\n"           \
+       DISCARD_ENTRY(number)                           \
+       ".section .altinstr_replacement, \"ax\"\n"      \
+       ALTINSTR_REPLACEMENT(newinstr, feature, number) \
+       ".popsection\n"
+
 /* alternative assembly primitive: */
-#define ALTERNATIVE(oldinstr, newinstr, feature)                        \
-        OLDINSTR(oldinstr)                                              \
-        ".pushsection .altinstructions,\"a\"\n"                         \
-        ALTINSTR_ENTRY(feature, 1)                                      \
-        ".popsection\n"                                                 \
-        ".pushsection .discard,\"aw\",@progbits\n"                      \
-        DISCARD_ENTRY(1)                                                \
-        ".popsection\n"                                                 \
-        ".pushsection .altinstr_replacement, \"ax\"\n"                  \
-        ALTINSTR_REPLACEMENT(newinstr, feature, 1)                      \
-        ".popsection"
+#define ALTERNATIVE(oldinstr, newinstr, feature)                         \
+       OLDINSTR(oldinstr)                                                \
+       ALTERNATIVE_N(newinstr, feature, 1)
+
+#define ALTERNATIVE_2(oldinstr, newinstr1, feature1, newinstr2, feature2) \
+       ALTERNATIVE(oldinstr, newinstr1, feature1)                        \
+       ALTERNATIVE_N(newinstr2, feature2, 2)
+
+#define ALTERNATIVE_3(oldinstr, newinstr1, feature1, newinstr2, feature2, \
+                     newinstr3, feature3)                                \
+       ALTERNATIVE_2(oldinstr, newinstr1, feature1, newinstr2, feature2) \
+       ALTERNATIVE_N(newinstr3, feature3, 3)
 
 /*
  * Alternative instructions for different CPU types or capabilities.
@@ -93,6 +103,37 @@ extern void alternative_instructions(void);
        asm volatile (ALTERNATIVE(oldinstr, newinstr, feature)          \
                      : output : input)
 
+/*
+ * This is similar to alternative_io. But it has two features and
+ * respective instructions.
+ *
+ * If CPU has feature2, newinstr2 is used.
+ * Otherwise, if CPU has feature1, newinstr1 is used.
+ * Otherwise, oldinstr is used.
+ */
+#define alternative_io_2(oldinstr, newinstr1, feature1, newinstr2,     \
+                        feature2, output, input...)                    \
+       asm volatile(ALTERNATIVE_2(oldinstr, newinstr1, feature1,       \
+                                  newinstr2, feature2)                 \
+                    : output : input)
+
+/*
+ * This is similar to alternative_io. But it has three features and
+ * respective instructions.
+ *
+ * If CPU has feature3, newinstr3 is used.
+ * Otherwise, if CPU has feature2, newinstr2 is used.
+ * Otherwise, if CPU has feature1, newinstr1 is used.
+ * Otherwise, oldinstr is used.
+ */
+#define alternative_io_3(oldinstr, newinstr1, feature1, newinstr2,     \
+                        feature2, newinstr3, feature3, output,         \
+                        input...)                                      \
+       asm volatile(ALTERNATIVE_3(oldinstr, newinstr1, feature1,       \
+                                  newinstr2, feature2, newinstr3,      \
+                                  feature3)                            \
+                    : output : input)
+
 /* Use this macro(s) if you need more than one output parameter. */
 #define ASM_OUTPUT2(a...) a
 
--
generated by git-patchbot for /home/xen/git/xen.git#master

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.