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 | |
| 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.
| -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 6a78ac58c194..02c8f5d22065 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 | ||
