diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index e7a4d2cd3968699b79fda9d41993f9c5f7f21d48..8090a0a4688271649cb562491655b2b7983e85fe 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] = {
      k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7,
 }; 
 
+extern char __vsyscall_0;
+
 /* Replace instructions with better alternatives for this CPU type.
 
    This runs before SMP is initialized to avoid SMP problems with
@@ -489,11 +491,17 @@ void apply_alternatives(void *start, void *end)
 	struct alt_instr *a; 
 	int diff, i, k;
 	for (a = start; (void *)a < end; a++) { 
+		u8 *instr;
+
 		if (!boot_cpu_has(a->cpuid))
 			continue;
 
 		BUG_ON(a->replacementlen > a->instrlen); 
-		__inline_memcpy(a->instr, a->replacement, a->replacementlen); 
+		instr = a->instr;
+		/* vsyscall code is not mapped yet. resolve it manually. */
+		if (instr >= (u8 *)VSYSCALL_START && instr < (u8*)VSYSCALL_END)
+			instr = __va(instr - (u8*)VSYSCALL_START + (u8*)__pa_symbol(&__vsyscall_0));
+		__inline_memcpy(instr, a->replacement, a->replacementlen);
 		diff = a->instrlen - a->replacementlen; 
 
 		/* Pad the rest with nops */
@@ -501,7 +509,7 @@ void apply_alternatives(void *start, void *end)
 			k = diff;
 			if (k > ASM_NOP_MAX)
 				k = ASM_NOP_MAX;
-			__inline_memcpy(a->instr + i, k8_nops[k], k); 
+			__inline_memcpy(instr + i, k8_nops[k], k);
 		} 
 	}
 }