Commit 7f6c5b046978d68e69bdc73433ead41612a2a1c9
Committed by
Linus Torvalds
1 parent
6e54d95f73
Exists in
master
and in
4 other branches
[PATCH] x86_64: Support alternative() in vsyscalls
The real vsyscall .text addresses are not mapped when the alternative() replacement runs early, so use some black magic to access them using the direct mapping. Signed-off-by: Andi Kleen <ak@suse.de> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Showing 1 changed file with 10 additions and 2 deletions Side-by-side Diff
arch/x86_64/kernel/setup.c
| ... | ... | @@ -478,6 +478,8 @@ |
| 478 | 478 | k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7, |
| 479 | 479 | }; |
| 480 | 480 | |
| 481 | +extern char __vsyscall_0; | |
| 482 | + | |
| 481 | 483 | /* Replace instructions with better alternatives for this CPU type. |
| 482 | 484 | |
| 483 | 485 | This runs before SMP is initialized to avoid SMP problems with |
| 484 | 486 | |
| ... | ... | @@ -489,11 +491,17 @@ |
| 489 | 491 | struct alt_instr *a; |
| 490 | 492 | int diff, i, k; |
| 491 | 493 | for (a = start; (void *)a < end; a++) { |
| 494 | + u8 *instr; | |
| 495 | + | |
| 492 | 496 | if (!boot_cpu_has(a->cpuid)) |
| 493 | 497 | continue; |
| 494 | 498 | |
| 495 | 499 | BUG_ON(a->replacementlen > a->instrlen); |
| 496 | - __inline_memcpy(a->instr, a->replacement, a->replacementlen); | |
| 500 | + instr = a->instr; | |
| 501 | + /* vsyscall code is not mapped yet. resolve it manually. */ | |
| 502 | + if (instr >= (u8 *)VSYSCALL_START && instr < (u8*)VSYSCALL_END) | |
| 503 | + instr = __va(instr - (u8*)VSYSCALL_START + (u8*)__pa_symbol(&__vsyscall_0)); | |
| 504 | + __inline_memcpy(instr, a->replacement, a->replacementlen); | |
| 497 | 505 | diff = a->instrlen - a->replacementlen; |
| 498 | 506 | |
| 499 | 507 | /* Pad the rest with nops */ |
| ... | ... | @@ -501,7 +509,7 @@ |
| 501 | 509 | k = diff; |
| 502 | 510 | if (k > ASM_NOP_MAX) |
| 503 | 511 | k = ASM_NOP_MAX; |
| 504 | - __inline_memcpy(a->instr + i, k8_nops[k], k); | |
| 512 | + __inline_memcpy(instr + i, k8_nops[k], k); | |
| 505 | 513 | } |
| 506 | 514 | } |
| 507 | 515 | } |