Commit 6b59257082e136fbbce1aa017575a451c0df0592

Authored by H. Peter Anvin
Committed by Ingo Molnar
1 parent 1d8a1f6b51

x86: actually merge <asm/alternative.h>

This actually merges <asm-x86/alternative_{32,64}.h> into
<asm-x86/alternative.h>.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

Showing 3 changed files with 159 additions and 325 deletions Side-by-side Diff

include/asm-x86/alternative.h
1   -#ifdef CONFIG_X86_32
2   -# include "alternative_32.h"
  1 +#ifndef _ASM_X86_ALTERNATIVE_H
  2 +#define _ASM_X86_ALTERNATIVE_H
  3 +
  4 +#include <linux/types.h>
  5 +#include <linux/stddef.h>
  6 +#include <asm/asm.h>
  7 +
  8 +/*
  9 + * Alternative inline assembly for SMP.
  10 + *
  11 + * The LOCK_PREFIX macro defined here replaces the LOCK and
  12 + * LOCK_PREFIX macros used everywhere in the source tree.
  13 + *
  14 + * SMP alternatives use the same data structures as the other
  15 + * alternatives and the X86_FEATURE_UP flag to indicate the case of a
  16 + * UP system running a SMP kernel. The existing apply_alternatives()
  17 + * works fine for patching a SMP kernel for UP.
  18 + *
  19 + * The SMP alternative tables can be kept after boot and contain both
  20 + * UP and SMP versions of the instructions to allow switching back to
  21 + * SMP at runtime, when hotplugging in a new CPU, which is especially
  22 + * useful in virtualized environments.
  23 + *
  24 + * The very common lock prefix is handled as special case in a
  25 + * separate table which is a pure address list without replacement ptr
  26 + * and size information. That keeps the table sizes small.
  27 + */
  28 +
  29 +#ifdef CONFIG_SMP
  30 +#define LOCK_PREFIX \
  31 + ".section .smp_locks,\"a\"\n" \
  32 + _ASM_ALIGN "\n" \
  33 + _ASM_PTR "661f\n" /* address */ \
  34 + ".previous\n" \
  35 + "661:\n\tlock; "
  36 +
  37 +#else /* ! CONFIG_SMP */
  38 +#define LOCK_PREFIX ""
  39 +#endif
  40 +
  41 +/* This must be included *after* the definition of LOCK_PREFIX */
  42 +#include <asm/cpufeature.h>
  43 +
  44 +struct alt_instr {
  45 + u8 *instr; /* original instruction */
  46 + u8 *replacement;
  47 + u8 cpuid; /* cpuid bit set for replacement */
  48 + u8 instrlen; /* length of original instruction */
  49 + u8 replacementlen; /* length of new instruction, <= instrlen */
  50 + u8 pad1;
  51 +#ifdef CONFIG_X86_64
  52 + u32 pad2;
  53 +#endif
  54 +};
  55 +
  56 +extern void alternative_instructions(void);
  57 +extern void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
  58 +
  59 +struct module;
  60 +
  61 +#ifdef CONFIG_SMP
  62 +extern void alternatives_smp_module_add(struct module *mod, char *name,
  63 + void *locks, void *locks_end,
  64 + void *text, void *text_end);
  65 +extern void alternatives_smp_module_del(struct module *mod);
  66 +extern void alternatives_smp_switch(int smp);
3 67 #else
4   -# include "alternative_64.h"
  68 +static inline void alternatives_smp_module_add(struct module *mod, char *name,
  69 + void *locks, void *locks_end,
  70 + void *text, void *text_end) {}
  71 +static inline void alternatives_smp_module_del(struct module *mod) {}
  72 +static inline void alternatives_smp_switch(int smp) {}
  73 +#endif /* CONFIG_SMP */
  74 +
  75 +/*
  76 + * Alternative instructions for different CPU types or capabilities.
  77 + *
  78 + * This allows to use optimized instructions even on generic binary
  79 + * kernels.
  80 + *
  81 + * length of oldinstr must be longer or equal the length of newinstr
  82 + * It can be padded with nops as needed.
  83 + *
  84 + * For non barrier like inlines please define new variants
  85 + * without volatile and memory clobber.
  86 + */
  87 +#define alternative(oldinstr, newinstr, feature) \
  88 + asm volatile ("661:\n\t" oldinstr "\n662:\n" \
  89 + ".section .altinstructions,\"a\"\n" \
  90 + _ASM_ALIGN "\n" \
  91 + _ASM_PTR "661b\n" /* label */ \
  92 + _ASM_PTR "663f\n" /* new instruction */ \
  93 + " .byte %c0\n" /* feature bit */ \
  94 + " .byte 662b-661b\n" /* sourcelen */ \
  95 + " .byte 664f-663f\n" /* replacementlen */ \
  96 + ".previous\n" \
  97 + ".section .altinstr_replacement,\"ax\"\n" \
  98 + "663:\n\t" newinstr "\n664:\n" /* replacement */ \
  99 + ".previous" :: "i" (feature) : "memory")
  100 +
  101 +/*
  102 + * Alternative inline assembly with input.
  103 + *
  104 + * Pecularities:
  105 + * No memory clobber here.
  106 + * Argument numbers start with 1.
  107 + * Best is to use constraints that are fixed size (like (%1) ... "r")
  108 + * If you use variable sized constraints like "m" or "g" in the
  109 + * replacement make sure to pad to the worst case length.
  110 + */
  111 +#define alternative_input(oldinstr, newinstr, feature, input...) \
  112 + asm volatile ("661:\n\t" oldinstr "\n662:\n" \
  113 + ".section .altinstructions,\"a\"\n" \
  114 + _ASM_ALIGN "\n" \
  115 + _ASM_PTR "661b\n" /* label */ \
  116 + _ASM_PTR "663f\n" /* new instruction */ \
  117 + " .byte %c0\n" /* feature bit */ \
  118 + " .byte 662b-661b\n" /* sourcelen */ \
  119 + " .byte 664f-663f\n" /* replacementlen */ \
  120 + ".previous\n" \
  121 + ".section .altinstr_replacement,\"ax\"\n" \
  122 + "663:\n\t" newinstr "\n664:\n" /* replacement */ \
  123 + ".previous" :: "i" (feature), ##input)
  124 +
  125 +/* Like alternative_input, but with a single output argument */
  126 +#define alternative_io(oldinstr, newinstr, feature, output, input...) \
  127 + asm volatile ("661:\n\t" oldinstr "\n662:\n" \
  128 + ".section .altinstructions,\"a\"\n" \
  129 + _ASM_ALIGN "\n" \
  130 + _ASM_PTR "661b\n" /* label */ \
  131 + _ASM_PTR "663f\n" /* new instruction */ \
  132 + " .byte %c[feat]\n" /* feature bit */ \
  133 + " .byte 662b-661b\n" /* sourcelen */ \
  134 + " .byte 664f-663f\n" /* replacementlen */ \
  135 + ".previous\n" \
  136 + ".section .altinstr_replacement,\"ax\"\n" \
  137 + "663:\n\t" newinstr "\n664:\n" /* replacement */ \
  138 + ".previous" : output : [feat] "i" (feature), ##input)
  139 +
  140 +/*
  141 + * use this macro(s) if you need more than one output parameter
  142 + * in alternative_io
  143 + */
  144 +#define ASM_OUTPUT2(a, b) a, b
  145 +
  146 +struct paravirt_patch_site;
  147 +#ifdef CONFIG_PARAVIRT
  148 +void apply_paravirt(struct paravirt_patch_site *start,
  149 + struct paravirt_patch_site *end);
  150 +#else
  151 +static inline void
  152 +apply_paravirt(struct paravirt_patch_site *start,
  153 + struct paravirt_patch_site *end)
  154 +{}
  155 +#define __parainstructions NULL
  156 +#define __parainstructions_end NULL
5 157 #endif
  158 +
  159 +extern void text_poke(void *addr, unsigned char *opcode, int len);
  160 +
  161 +#endif /* _ASM_X86_ALTERNATIVE_H */
include/asm-x86/alternative_32.h
1   -#ifndef _I386_ALTERNATIVE_H
2   -#define _I386_ALTERNATIVE_H
3   -
4   -#include <linux/types.h>
5   -#include <linux/stddef.h>
6   -#include <asm/asm.h>
7   -
8   -/*
9   - * Alternative inline assembly for SMP.
10   - *
11   - * The LOCK_PREFIX macro defined here replaces the LOCK and
12   - * LOCK_PREFIX macros used everywhere in the source tree.
13   - *
14   - * SMP alternatives use the same data structures as the other
15   - * alternatives and the X86_FEATURE_UP flag to indicate the case of a
16   - * UP system running a SMP kernel. The existing apply_alternatives()
17   - * works fine for patching a SMP kernel for UP.
18   - *
19   - * The SMP alternative tables can be kept after boot and contain both
20   - * UP and SMP versions of the instructions to allow switching back to
21   - * SMP at runtime, when hotplugging in a new CPU, which is especially
22   - * useful in virtualized environments.
23   - *
24   - * The very common lock prefix is handled as special case in a
25   - * separate table which is a pure address list without replacement ptr
26   - * and size information. That keeps the table sizes small.
27   - */
28   -
29   -#ifdef CONFIG_SMP
30   -#define LOCK_PREFIX \
31   - ".section .smp_locks,\"a\"\n" \
32   - _ASM_ALIGN "\n" \
33   - _ASM_PTR "661f\n" /* address */ \
34   - ".previous\n" \
35   - "661:\n\tlock; "
36   -
37   -#else /* ! CONFIG_SMP */
38   -#define LOCK_PREFIX ""
39   -#endif
40   -
41   -/* This must be included *after* the definition of LOCK_PREFIX */
42   -#include <asm/cpufeature.h>
43   -
44   -struct alt_instr {
45   - u8 *instr; /* original instruction */
46   - u8 *replacement;
47   - u8 cpuid; /* cpuid bit set for replacement */
48   - u8 instrlen; /* length of original instruction */
49   - u8 replacementlen; /* length of new instruction, <= instrlen */
50   - u8 pad1;
51   -#ifdef CONFIG_X86_64
52   - u32 pad2;
53   -#endif
54   -};
55   -
56   -extern void alternative_instructions(void);
57   -extern void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
58   -
59   -struct module;
60   -
61   -#ifdef CONFIG_SMP
62   -extern void alternatives_smp_module_add(struct module *mod, char *name,
63   - void *locks, void *locks_end,
64   - void *text, void *text_end);
65   -extern void alternatives_smp_module_del(struct module *mod);
66   -extern void alternatives_smp_switch(int smp);
67   -#else
68   -static inline void alternatives_smp_module_add(struct module *mod, char *name,
69   - void *locks, void *locks_end,
70   - void *text, void *text_end) {}
71   -static inline void alternatives_smp_module_del(struct module *mod) {}
72   -static inline void alternatives_smp_switch(int smp) {}
73   -#endif /* CONFIG_SMP */
74   -
75   -/*
76   - * Alternative instructions for different CPU types or capabilities.
77   - *
78   - * This allows to use optimized instructions even on generic binary
79   - * kernels.
80   - *
81   - * length of oldinstr must be longer or equal the length of newinstr
82   - * It can be padded with nops as needed.
83   - *
84   - * For non barrier like inlines please define new variants
85   - * without volatile and memory clobber.
86   - */
87   -#define alternative(oldinstr, newinstr, feature) \
88   - asm volatile ("661:\n\t" oldinstr "\n662:\n" \
89   - ".section .altinstructions,\"a\"\n" \
90   - _ASM_ALIGN "\n" \
91   - _ASM_PTR "661b\n" /* label */ \
92   - _ASM_PTR "663f\n" /* new instruction */ \
93   - " .byte %c0\n" /* feature bit */ \
94   - " .byte 662b-661b\n" /* sourcelen */ \
95   - " .byte 664f-663f\n" /* replacementlen */ \
96   - ".previous\n" \
97   - ".section .altinstr_replacement,\"ax\"\n" \
98   - "663:\n\t" newinstr "\n664:\n" /* replacement */ \
99   - ".previous" :: "i" (feature) : "memory")
100   -
101   -/*
102   - * Alternative inline assembly with input.
103   - *
104   - * Pecularities:
105   - * No memory clobber here.
106   - * Argument numbers start with 1.
107   - * Best is to use constraints that are fixed size (like (%1) ... "r")
108   - * If you use variable sized constraints like "m" or "g" in the
109   - * replacement make sure to pad to the worst case length.
110   - */
111   -#define alternative_input(oldinstr, newinstr, feature, input...) \
112   - asm volatile ("661:\n\t" oldinstr "\n662:\n" \
113   - ".section .altinstructions,\"a\"\n" \
114   - _ASM_ALIGN "\n" \
115   - _ASM_PTR "661b\n" /* label */ \
116   - _ASM_PTR "663f\n" /* new instruction */ \
117   - " .byte %c0\n" /* feature bit */ \
118   - " .byte 662b-661b\n" /* sourcelen */ \
119   - " .byte 664f-663f\n" /* replacementlen */ \
120   - ".previous\n" \
121   - ".section .altinstr_replacement,\"ax\"\n" \
122   - "663:\n\t" newinstr "\n664:\n" /* replacement */ \
123   - ".previous" :: "i" (feature), ##input)
124   -
125   -/* Like alternative_input, but with a single output argument */
126   -#define alternative_io(oldinstr, newinstr, feature, output, input...) \
127   - asm volatile ("661:\n\t" oldinstr "\n662:\n" \
128   - ".section .altinstructions,\"a\"\n" \
129   - _ASM_ALIGN "\n" \
130   - _ASM_PTR "661b\n" /* label */ \
131   - _ASM_PTR "663f\n" /* new instruction */ \
132   - " .byte %c[feat]\n" /* feature bit */ \
133   - " .byte 662b-661b\n" /* sourcelen */ \
134   - " .byte 664f-663f\n" /* replacementlen */ \
135   - ".previous\n" \
136   - ".section .altinstr_replacement,\"ax\"\n" \
137   - "663:\n\t" newinstr "\n664:\n" /* replacement */ \
138   - ".previous" : output : [feat] "i" (feature), ##input)
139   -
140   -/*
141   - * use this macro(s) if you need more than one output parameter
142   - * in alternative_io
143   - */
144   -#define ASM_OUTPUT2(a, b) a, b
145   -
146   -struct paravirt_patch_site;
147   -#ifdef CONFIG_PARAVIRT
148   -void apply_paravirt(struct paravirt_patch_site *start,
149   - struct paravirt_patch_site *end);
150   -#else
151   -static inline void
152   -apply_paravirt(struct paravirt_patch_site *start,
153   - struct paravirt_patch_site *end)
154   -{}
155   -#define __parainstructions NULL
156   -#define __parainstructions_end NULL
157   -#endif
158   -
159   -extern void text_poke(void *addr, unsigned char *opcode, int len);
160   -
161   -#endif /* _I386_ALTERNATIVE_H */
include/asm-x86/alternative_64.h
1   -#ifndef _X86_64_ALTERNATIVE_H
2   -#define _X86_64_ALTERNATIVE_H
3   -
4   -#include <linux/types.h>
5   -#include <linux/stddef.h>
6   -#include <asm/asm.h>
7   -
8   -/*
9   - * Alternative inline assembly for SMP.
10   - *
11   - * The LOCK_PREFIX macro defined here replaces the LOCK and
12   - * LOCK_PREFIX macros used everywhere in the source tree.
13   - *
14   - * SMP alternatives use the same data structures as the other
15   - * alternatives and the X86_FEATURE_UP flag to indicate the case of a
16   - * UP system running a SMP kernel. The existing apply_alternatives()
17   - * works fine for patching a SMP kernel for UP.
18   - *
19   - * The SMP alternative tables can be kept after boot and contain both
20   - * UP and SMP versions of the instructions to allow switching back to
21   - * SMP at runtime, when hotplugging in a new CPU, which is especially
22   - * useful in virtualized environments.
23   - *
24   - * The very common lock prefix is handled as special case in a
25   - * separate table which is a pure address list without replacement ptr
26   - * and size information. That keeps the table sizes small.
27   - */
28   -
29   -#ifdef CONFIG_SMP
30   -#define LOCK_PREFIX \
31   - ".section .smp_locks,\"a\"\n" \
32   - _ASM_ALIGN "\n" \
33   - _ASM_PTR "661f\n" /* address */ \
34   - ".previous\n" \
35   - "661:\n\tlock; "
36   -
37   -#else /* ! CONFIG_SMP */
38   -#define LOCK_PREFIX ""
39   -#endif
40   -
41   -/* This must be included *after* the definition of LOCK_PREFIX */
42   -#include <asm/cpufeature.h>
43   -
44   -struct alt_instr {
45   - u8 *instr; /* original instruction */
46   - u8 *replacement;
47   - u8 cpuid; /* cpuid bit set for replacement */
48   - u8 instrlen; /* length of original instruction */
49   - u8 replacementlen; /* length of new instruction, <= instrlen */
50   - u8 pad1;
51   -#ifdef CONFIG_X86_64
52   - u32 pad2;
53   -#endif
54   -};
55   -
56   -extern void alternative_instructions(void);
57   -extern void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
58   -
59   -struct module;
60   -
61   -#ifdef CONFIG_SMP
62   -extern void alternatives_smp_module_add(struct module *mod, char *name,
63   - void *locks, void *locks_end,
64   - void *text, void *text_end);
65   -extern void alternatives_smp_module_del(struct module *mod);
66   -extern void alternatives_smp_switch(int smp);
67   -#else
68   -static inline void alternatives_smp_module_add(struct module *mod, char *name,
69   - void *locks, void *locks_end,
70   - void *text, void *text_end) {}
71   -static inline void alternatives_smp_module_del(struct module *mod) {}
72   -static inline void alternatives_smp_switch(int smp) {}
73   -#endif /* CONFIG_SMP */
74   -
75   -/*
76   - * Alternative instructions for different CPU types or capabilities.
77   - *
78   - * This allows to use optimized instructions even on generic binary
79   - * kernels.
80   - *
81   - * length of oldinstr must be longer or equal the length of newinstr
82   - * It can be padded with nops as needed.
83   - *
84   - * For non barrier like inlines please define new variants
85   - * without volatile and memory clobber.
86   - */
87   -#define alternative(oldinstr, newinstr, feature) \
88   - asm volatile ("661:\n\t" oldinstr "\n662:\n" \
89   - ".section .altinstructions,\"a\"\n" \
90   - _ASM_ALIGN "\n" \
91   - _ASM_PTR "661b\n" /* label */ \
92   - _ASM_PTR "663f\n" /* new instruction */ \
93   - " .byte %c0\n" /* feature bit */ \
94   - " .byte 662b-661b\n" /* sourcelen */ \
95   - " .byte 664f-663f\n" /* replacementlen */ \
96   - ".previous\n" \
97   - ".section .altinstr_replacement,\"ax\"\n" \
98   - "663:\n\t" newinstr "\n664:\n" /* replacement */ \
99   - ".previous" :: "i" (feature) : "memory")
100   -
101   -/*
102   - * Alternative inline assembly with input.
103   - *
104   - * Pecularities:
105   - * No memory clobber here.
106   - * Argument numbers start with 1.
107   - * Best is to use constraints that are fixed size (like (%1) ... "r")
108   - * If you use variable sized constraints like "m" or "g" in the
109   - * replacement make sure to pad to the worst case length.
110   - */
111   -#define alternative_input(oldinstr, newinstr, feature, input...) \
112   - asm volatile ("661:\n\t" oldinstr "\n662:\n" \
113   - ".section .altinstructions,\"a\"\n" \
114   - _ASM_ALIGN "\n" \
115   - _ASM_PTR "661b\n" /* label */ \
116   - _ASM_PTR "663f\n" /* new instruction */ \
117   - " .byte %c0\n" /* feature bit */ \
118   - " .byte 662b-661b\n" /* sourcelen */ \
119   - " .byte 664f-663f\n" /* replacementlen */ \
120   - ".previous\n" \
121   - ".section .altinstr_replacement,\"ax\"\n" \
122   - "663:\n\t" newinstr "\n664:\n" /* replacement */ \
123   - ".previous" :: "i" (feature), ##input)
124   -
125   -/* Like alternative_input, but with a single output argument */
126   -#define alternative_io(oldinstr, newinstr, feature, output, input...) \
127   - asm volatile ("661:\n\t" oldinstr "\n662:\n" \
128   - ".section .altinstructions,\"a\"\n" \
129   - _ASM_ALIGN "\n" \
130   - _ASM_PTR "661b\n" /* label */ \
131   - _ASM_PTR "663f\n" /* new instruction */ \
132   - " .byte %c[feat]\n" /* feature bit */ \
133   - " .byte 662b-661b\n" /* sourcelen */ \
134   - " .byte 664f-663f\n" /* replacementlen */ \
135   - ".previous\n" \
136   - ".section .altinstr_replacement,\"ax\"\n" \
137   - "663:\n\t" newinstr "\n664:\n" /* replacement */ \
138   - ".previous" : output : [feat] "i" (feature), ##input)
139   -
140   -/*
141   - * use this macro(s) if you need more than one output parameter
142   - * in alternative_io
143   - */
144   -#define ASM_OUTPUT2(a, b) a, b
145   -
146   -struct paravirt_patch_site;
147   -#ifdef CONFIG_PARAVIRT
148   -void apply_paravirt(struct paravirt_patch_site *start,
149   - struct paravirt_patch_site *end);
150   -#else
151   -static inline void
152   -apply_paravirt(struct paravirt_patch_site *start,
153   - struct paravirt_patch_site *end)
154   -{}
155   -#define __parainstructions NULL
156   -#define __parainstructions_end NULL
157   -#endif
158   -
159   -extern void text_poke(void *addr, unsigned char *opcode, int len);
160   -
161   -#endif /* _X86_64_ALTERNATIVE_H */