Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik...
[powerpc.git] / include / asm-i386 / alternative.h
index 96adbab..0f70b37 100644 (file)
@@ -1,10 +1,8 @@
 #ifndef _I386_ALTERNATIVE_H
 #define _I386_ALTERNATIVE_H
 
-#ifdef __KERNEL__
-
 #include <asm/types.h>
-
+#include <linux/stddef.h>
 #include <linux/types.h>
 
 struct alt_instr {
@@ -16,6 +14,7 @@ struct alt_instr {
        u8  pad;
 };
 
+extern void alternative_instructions(void);
 extern void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
 
 struct module;
@@ -31,9 +30,7 @@ static inline void alternatives_smp_module_add(struct module *mod, char *name,
                                        void *text, void *text_end) {}
 static inline void alternatives_smp_module_del(struct module *mod) {}
 static inline void alternatives_smp_switch(int smp) {}
-#endif
-
-#endif
+#endif /* CONFIG_SMP */
 
 /*
  * Alternative instructions for different CPU types or capabilities.
@@ -85,12 +82,24 @@ static inline void alternatives_smp_switch(int smp) {}
                      "663:\n\t" newinstr "\n664:\n"   /* replacement */\
                      ".previous" :: "i" (feature), ##input)
 
+/* Like alternative_input, but with a single output argument */
+#define alternative_io(oldinstr, newinstr, feature, 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 */ \
+                     "  .byte %c[feat]\n"        /* feature bit */     \
+                     "  .byte 662b-661b\n"       /* sourcelen */       \
+                     "  .byte 664f-663f\n"       /* replacementlen */  \
+                     ".previous\n"                                     \
+                     ".section .altinstr_replacement,\"ax\"\n"         \
+                     "663:\n\t" newinstr "\n664:\n"   /* replacement */ \
+                     ".previous" : output : [feat] "i" (feature), ##input)
+
 /*
  * Alternative inline assembly for SMP.
  *
- * alternative_smp() takes two versions (SMP first, UP second) and is
- * for more complex stuff such as spinlocks.
- *
  * The LOCK_PREFIX macro defined here replaces the LOCK and
  * LOCK_PREFIX macros used everywhere in the source tree.
  *
@@ -110,21 +119,6 @@ static inline void alternatives_smp_switch(int smp) {}
  */
 
 #ifdef CONFIG_SMP
-#define alternative_smp(smpinstr, upinstr, args...)                    \
-       asm volatile ("661:\n\t" smpinstr "\n662:\n"                    \
-                     ".section .smp_altinstructions,\"a\"\n"           \
-                     "  .align 4\n"                                    \
-                     "  .long 661b\n"            /* label */           \
-                     "  .long 663f\n"            /* new instruction */ \
-                     "  .byte 0x68\n"            /* X86_FEATURE_UP */  \
-                     "  .byte 662b-661b\n"       /* sourcelen */       \
-                     "  .byte 664f-663f\n"       /* replacementlen */  \
-                     ".previous\n"                                     \
-                     ".section .smp_altinstr_replacement,\"awx\"\n"    \
-                     "663:\n\t" upinstr "\n"     /* replacement */     \
-                     "664:\n\t.fill 662b-661b,1,0x42\n" /* space for original */ \
-                     ".previous" : args)
-
 #define LOCK_PREFIX \
                ".section .smp_locks,\"a\"\n"   \
                "  .align 4\n"                  \
@@ -133,9 +127,20 @@ static inline void alternatives_smp_switch(int smp) {}
                "661:\n\tlock; "
 
 #else /* ! CONFIG_SMP */
-#define alternative_smp(smpinstr, upinstr, args...) \
-       asm volatile (upinstr : args)
 #define LOCK_PREFIX ""
 #endif
 
+struct paravirt_patch_site;
+#ifdef CONFIG_PARAVIRT
+void apply_paravirt(struct paravirt_patch_site *start,
+                   struct paravirt_patch_site *end);
+#else
+static inline void
+apply_paravirt(struct paravirt_patch_site *start,
+              struct paravirt_patch_site *end)
+{}
+#define __parainstructions     NULL
+#define __parainstructions_end NULL
+#endif
+
 #endif /* _I386_ALTERNATIVE_H */