Blame view

kernel/linux-rt-4.4.41/arch/x86/include/asm/alternative-asm.h 2.32 KB
5113f6f70   김현기   kernel add
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
  #ifndef _ASM_X86_ALTERNATIVE_ASM_H
  #define _ASM_X86_ALTERNATIVE_ASM_H
  
  #ifdef __ASSEMBLY__
  
  #include <asm/asm.h>
  
  #ifdef CONFIG_SMP
  	.macro LOCK_PREFIX
  672:	lock
  	.pushsection .smp_locks,"a"
  	.balign 4
  	.long 672b - .
  	.popsection
  	.endm
  #else
  	.macro LOCK_PREFIX
  	.endm
  #endif
  
  /*
   * Issue one struct alt_instr descriptor entry (need to put it into
   * the section .altinstructions, see below). This entry contains
   * enough information for the alternatives patching code to patch an
   * instruction. See apply_alternatives().
   */
  .macro altinstruction_entry orig alt feature orig_len alt_len pad_len
  	.long \orig - .
  	.long \alt - .
  	.word \feature
  	.byte \orig_len
  	.byte \alt_len
  	.byte \pad_len
  .endm
  
  /*
   * Define an alternative between two instructions. If @feature is
   * present, early code in apply_alternatives() replaces @oldinstr with
   * @newinstr. ".skip" directive takes care of proper instruction padding
   * in case @newinstr is longer than @oldinstr.
   */
  .macro ALTERNATIVE oldinstr, newinstr, feature
  140:
  	\oldinstr
  141:
  	.skip -(((144f-143f)-(141b-140b)) > 0) * ((144f-143f)-(141b-140b)),0x90
  142:
  
  	.pushsection .altinstructions,"a"
  	altinstruction_entry 140b,143f,\feature,142b-140b,144f-143f,142b-141b
  	.popsection
  
  	.pushsection .altinstr_replacement,"ax"
  143:
  	
  ewinstr
  144:
  	.popsection
  .endm
  
  #define old_len			141b-140b
  #define new_len1		144f-143f
  #define new_len2		145f-144f
  
  /*
   * max without conditionals. Idea adapted from:
   * http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax
   */
  #define alt_max_short(a, b)	((a) ^ (((a) ^ (b)) & -(-((a) < (b)))))
  
  
  /*
   * Same as ALTERNATIVE macro above but for two alternatives. If CPU
   * has @feature1, it replaces @oldinstr with @newinstr1. If CPU has
   * @feature2, it replaces @oldinstr with @feature2.
   */
  .macro ALTERNATIVE_2 oldinstr, newinstr1, feature1, newinstr2, feature2
  140:
  	\oldinstr
  141:
  	.skip -((alt_max_short(new_len1, new_len2) - (old_len)) > 0) * \
  		(alt_max_short(new_len1, new_len2) - (old_len)),0x90
  142:
  
  	.pushsection .altinstructions,"a"
  	altinstruction_entry 140b,143f,\feature1,142b-140b,144f-143f,142b-141b
  	altinstruction_entry 140b,144f,\feature2,142b-140b,145f-144f,142b-141b
  	.popsection
  
  	.pushsection .altinstr_replacement,"ax"
  143:
  	
  ewinstr1
  144:
  	
  ewinstr2
  145:
  	.popsection
  .endm
  
  #endif  /*  __ASSEMBLY__  */
  
  #endif /* _ASM_X86_ALTERNATIVE_ASM_H */