diff options
-rw-r--r-- | arch/x86_64/kernel/setup.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index e7a4d2cd3968..8090a0a46882 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c | |||
@@ -478,6 +478,8 @@ static unsigned char *k8_nops[ASM_NOP_MAX+1] = { | |||
478 | k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7, | 478 | k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7, |
479 | }; | 479 | }; |
480 | 480 | ||
481 | extern char __vsyscall_0; | ||
482 | |||
481 | /* Replace instructions with better alternatives for this CPU type. | 483 | /* Replace instructions with better alternatives for this CPU type. |
482 | 484 | ||
483 | This runs before SMP is initialized to avoid SMP problems with | 485 | This runs before SMP is initialized to avoid SMP problems with |
@@ -489,11 +491,17 @@ void apply_alternatives(void *start, void *end) | |||
489 | struct alt_instr *a; | 491 | struct alt_instr *a; |
490 | int diff, i, k; | 492 | int diff, i, k; |
491 | for (a = start; (void *)a < end; a++) { | 493 | for (a = start; (void *)a < end; a++) { |
494 | u8 *instr; | ||
495 | |||
492 | if (!boot_cpu_has(a->cpuid)) | 496 | if (!boot_cpu_has(a->cpuid)) |
493 | continue; | 497 | continue; |
494 | 498 | ||
495 | BUG_ON(a->replacementlen > a->instrlen); | 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 | diff = a->instrlen - a->replacementlen; | 505 | diff = a->instrlen - a->replacementlen; |
498 | 506 | ||
499 | /* Pad the rest with nops */ | 507 | /* Pad the rest with nops */ |
@@ -501,7 +509,7 @@ void apply_alternatives(void *start, void *end) | |||
501 | k = diff; | 509 | k = diff; |
502 | if (k > ASM_NOP_MAX) | 510 | if (k > ASM_NOP_MAX) |
503 | k = ASM_NOP_MAX; | 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 | } |