diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-24 13:39:17 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-24 13:39:17 -0400 |
commit | 793ae77469121227cd910c4b99f24be1de34bcca (patch) | |
tree | ca8b6bbafab35c5c1099c54696c36dc0b8c17cf7 /include | |
parent | 59a49e38711a146dc0bef4837c825b5422335460 (diff) |
Add "memory" clobbers to the x86 inline asm of strncmp and friends
They don't actually clobber memory, but gcc doesn't even know they
_read_ memory, so can apparently re-order memory accesses around them.
Which obviously does the wrong thing if the memory access happens to
change the memory that the compare function is accessing..
Verified to fix a strange boot problem by Jens Axboe.
Diffstat (limited to 'include')
-rw-r--r-- | include/asm-i386/string.h | 32 |
1 files changed, 22 insertions, 10 deletions
diff --git a/include/asm-i386/string.h b/include/asm-i386/string.h index 6a78ac58c19..02c8f5d2206 100644 --- a/include/asm-i386/string.h +++ b/include/asm-i386/string.h | |||
@@ -116,7 +116,8 @@ __asm__ __volatile__( | |||
116 | "orb $1,%%al\n" | 116 | "orb $1,%%al\n" |
117 | "3:" | 117 | "3:" |
118 | :"=a" (__res), "=&S" (d0), "=&D" (d1) | 118 | :"=a" (__res), "=&S" (d0), "=&D" (d1) |
119 | :"1" (cs),"2" (ct)); | 119 | :"1" (cs),"2" (ct) |
120 | :"memory"); | ||
120 | return __res; | 121 | return __res; |
121 | } | 122 | } |
122 | 123 | ||
@@ -138,8 +139,9 @@ __asm__ __volatile__( | |||
138 | "3:\tsbbl %%eax,%%eax\n\t" | 139 | "3:\tsbbl %%eax,%%eax\n\t" |
139 | "orb $1,%%al\n" | 140 | "orb $1,%%al\n" |
140 | "4:" | 141 | "4:" |
141 | :"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2) | 142 | :"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2) |
142 | :"1" (cs),"2" (ct),"3" (count)); | 143 | :"1" (cs),"2" (ct),"3" (count) |
144 | :"memory"); | ||
143 | return __res; | 145 | return __res; |
144 | } | 146 | } |
145 | 147 | ||
@@ -158,7 +160,9 @@ __asm__ __volatile__( | |||
158 | "movl $1,%1\n" | 160 | "movl $1,%1\n" |
159 | "2:\tmovl %1,%0\n\t" | 161 | "2:\tmovl %1,%0\n\t" |
160 | "decl %0" | 162 | "decl %0" |
161 | :"=a" (__res), "=&S" (d0) : "1" (s),"0" (c)); | 163 | :"=a" (__res), "=&S" (d0) |
164 | :"1" (s),"0" (c) | ||
165 | :"memory"); | ||
162 | return __res; | 166 | return __res; |
163 | } | 167 | } |
164 | 168 | ||
@@ -175,7 +179,9 @@ __asm__ __volatile__( | |||
175 | "leal -1(%%esi),%0\n" | 179 | "leal -1(%%esi),%0\n" |
176 | "2:\ttestb %%al,%%al\n\t" | 180 | "2:\ttestb %%al,%%al\n\t" |
177 | "jne 1b" | 181 | "jne 1b" |
178 | :"=g" (__res), "=&S" (d0), "=&a" (d1) :"0" (0),"1" (s),"2" (c)); | 182 | :"=g" (__res), "=&S" (d0), "=&a" (d1) |
183 | :"0" (0),"1" (s),"2" (c) | ||
184 | :"memory"); | ||
179 | return __res; | 185 | return __res; |
180 | } | 186 | } |
181 | 187 | ||
@@ -189,7 +195,9 @@ __asm__ __volatile__( | |||
189 | "scasb\n\t" | 195 | "scasb\n\t" |
190 | "notl %0\n\t" | 196 | "notl %0\n\t" |
191 | "decl %0" | 197 | "decl %0" |
192 | :"=c" (__res), "=&D" (d0) :"1" (s),"a" (0), "0" (0xffffffffu)); | 198 | :"=c" (__res), "=&D" (d0) |
199 | :"1" (s),"a" (0), "0" (0xffffffffu) | ||
200 | :"memory"); | ||
193 | return __res; | 201 | return __res; |
194 | } | 202 | } |
195 | 203 | ||
@@ -333,7 +341,9 @@ __asm__ __volatile__( | |||
333 | "je 1f\n\t" | 341 | "je 1f\n\t" |
334 | "movl $1,%0\n" | 342 | "movl $1,%0\n" |
335 | "1:\tdecl %0" | 343 | "1:\tdecl %0" |
336 | :"=D" (__res), "=&c" (d0) : "a" (c),"0" (cs),"1" (count)); | 344 | :"=D" (__res), "=&c" (d0) |
345 | :"a" (c),"0" (cs),"1" (count) | ||
346 | :"memory"); | ||
337 | return __res; | 347 | return __res; |
338 | } | 348 | } |
339 | 349 | ||
@@ -369,7 +379,7 @@ __asm__ __volatile__( | |||
369 | "je 2f\n\t" | 379 | "je 2f\n\t" |
370 | "stosb\n" | 380 | "stosb\n" |
371 | "2:" | 381 | "2:" |
372 | : "=&c" (d0), "=&D" (d1) | 382 | :"=&c" (d0), "=&D" (d1) |
373 | :"a" (c), "q" (count), "0" (count/4), "1" ((long) s) | 383 | :"a" (c), "q" (count), "0" (count/4), "1" ((long) s) |
374 | :"memory"); | 384 | :"memory"); |
375 | return (s); | 385 | return (s); |
@@ -392,7 +402,8 @@ __asm__ __volatile__( | |||
392 | "jne 1b\n" | 402 | "jne 1b\n" |
393 | "3:\tsubl %2,%0" | 403 | "3:\tsubl %2,%0" |
394 | :"=a" (__res), "=&d" (d0) | 404 | :"=a" (__res), "=&d" (d0) |
395 | :"c" (s),"1" (count)); | 405 | :"c" (s),"1" (count) |
406 | :"memory"); | ||
396 | return __res; | 407 | return __res; |
397 | } | 408 | } |
398 | /* end of additional stuff */ | 409 | /* end of additional stuff */ |
@@ -473,7 +484,8 @@ static inline void * memscan(void * addr, int c, size_t size) | |||
473 | "dec %%edi\n" | 484 | "dec %%edi\n" |
474 | "1:" | 485 | "1:" |
475 | : "=D" (addr), "=c" (size) | 486 | : "=D" (addr), "=c" (size) |
476 | : "0" (addr), "1" (size), "a" (c)); | 487 | : "0" (addr), "1" (size), "a" (c) |
488 | : "memory"); | ||
477 | return addr; | 489 | return addr; |
478 | } | 490 | } |
479 | 491 | ||