x86: clean up text_poke()
Clean up the codepath, remove alignment restrictions and do sanity checking of the end result, to make sure we patched the right site. Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
committed by
Ingo Molnar
parent
8b132ecbcf
commit
b7b66baa8b
@@ -511,13 +511,17 @@ void *__kprobes text_poke(void *addr, const void *opcode, size_t len)
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
char *vaddr;
|
char *vaddr;
|
||||||
int nr_pages = 2;
|
int nr_pages = 2;
|
||||||
|
struct page *pages[2];
|
||||||
|
int i;
|
||||||
|
|
||||||
BUG_ON(len > sizeof(long));
|
if (!core_kernel_text((unsigned long)addr)) {
|
||||||
BUG_ON((((long)addr + len - 1) & ~(sizeof(long) - 1))
|
pages[0] = vmalloc_to_page(addr);
|
||||||
- ((long)addr & ~(sizeof(long) - 1)));
|
pages[1] = vmalloc_to_page(addr + PAGE_SIZE);
|
||||||
if (core_kernel_text((unsigned long)addr)) {
|
} else {
|
||||||
struct page *pages[2] = { virt_to_page(addr),
|
pages[0] = virt_to_page(addr);
|
||||||
virt_to_page(addr + PAGE_SIZE) };
|
pages[1] = virt_to_page(addr + PAGE_SIZE);
|
||||||
|
}
|
||||||
|
BUG_ON(!pages[0]);
|
||||||
if (!pages[1])
|
if (!pages[1])
|
||||||
nr_pages = 1;
|
nr_pages = 1;
|
||||||
vaddr = vmap(pages, nr_pages, VM_MAP, PAGE_KERNEL);
|
vaddr = vmap(pages, nr_pages, VM_MAP, PAGE_KERNEL);
|
||||||
@@ -526,16 +530,10 @@ void *__kprobes text_poke(void *addr, const void *opcode, size_t len)
|
|||||||
memcpy(&vaddr[(unsigned long)addr & ~PAGE_MASK], opcode, len);
|
memcpy(&vaddr[(unsigned long)addr & ~PAGE_MASK], opcode, len);
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
vunmap(vaddr);
|
vunmap(vaddr);
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* modules are in vmalloc'ed memory, always writable.
|
|
||||||
*/
|
|
||||||
local_irq_save(flags);
|
|
||||||
memcpy(addr, opcode, len);
|
|
||||||
local_irq_restore(flags);
|
|
||||||
}
|
|
||||||
sync_core();
|
sync_core();
|
||||||
/* Could also do a CLFLUSH here to speed up CPU recovery; but
|
/* Could also do a CLFLUSH here to speed up CPU recovery; but
|
||||||
that causes hangs on some VIA CPUs. */
|
that causes hangs on some VIA CPUs. */
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
BUG_ON(((char *)addr)[i] != ((char *)opcode)[i]);
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user