diff options
Diffstat (limited to 'arch/i386/kernel/alternative.c')
-rw-r--r-- | arch/i386/kernel/alternative.c | 14 |
1 files changed, 2 insertions, 12 deletions
diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c index c3750c2c4113..c85598acb8fd 100644 --- a/arch/i386/kernel/alternative.c +++ b/arch/i386/kernel/alternative.c | |||
@@ -430,22 +430,12 @@ void __init alternative_instructions(void) | |||
430 | * And on the local CPU you need to be protected again NMI or MCE handlers | 430 | * And on the local CPU you need to be protected again NMI or MCE handlers |
431 | * seeing an inconsistent instruction while you patch. | 431 | * seeing an inconsistent instruction while you patch. |
432 | */ | 432 | */ |
433 | void __kprobes text_poke(void *oaddr, unsigned char *opcode, int len) | 433 | void __kprobes text_poke(void *addr, unsigned char *opcode, int len) |
434 | { | 434 | { |
435 | u8 *addr = oaddr; | ||
436 | if (!pte_write(*lookup_address((unsigned long)addr))) { | ||
437 | struct page *p[2] = { virt_to_page(addr), virt_to_page(addr+PAGE_SIZE) }; | ||
438 | addr = vmap(p, 2, VM_MAP, PAGE_KERNEL); | ||
439 | if (!addr) | ||
440 | return; | ||
441 | addr += ((unsigned long)oaddr) % PAGE_SIZE; | ||
442 | } | ||
443 | memcpy(addr, opcode, len); | 435 | memcpy(addr, opcode, len); |
444 | sync_core(); | 436 | sync_core(); |
445 | /* Not strictly needed, but can speed CPU recovery up. Ignore cross cacheline | 437 | /* Not strictly needed, but can speed CPU recovery up. Ignore cross cacheline |
446 | case. */ | 438 | case. */ |
447 | if (cpu_has_clflush) | 439 | if (cpu_has_clflush) |
448 | asm("clflush (%0) " :: "r" (oaddr) : "memory"); | 440 | asm("clflush (%0) " :: "r" (addr) : "memory"); |
449 | if (addr != oaddr) | ||
450 | vunmap(addr); | ||
451 | } | 441 | } |