|
@@ -511,31 +511,29 @@ 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));
|
|
|
|
- BUG_ON((((long)addr + len - 1) & ~(sizeof(long) - 1))
|
|
|
|
- - ((long)addr & ~(sizeof(long) - 1)));
|
|
|
|
- if (core_kernel_text((unsigned long)addr)) {
|
|
|
|
- struct page *pages[2] = { virt_to_page(addr),
|
|
|
|
- virt_to_page(addr + PAGE_SIZE) };
|
|
|
|
- if (!pages[1])
|
|
|
|
- nr_pages = 1;
|
|
|
|
- vaddr = vmap(pages, nr_pages, VM_MAP, PAGE_KERNEL);
|
|
|
|
- BUG_ON(!vaddr);
|
|
|
|
- local_irq_save(flags);
|
|
|
|
- memcpy(&vaddr[(unsigned long)addr & ~PAGE_MASK], opcode, len);
|
|
|
|
- local_irq_restore(flags);
|
|
|
|
- vunmap(vaddr);
|
|
|
|
|
|
+ if (!core_kernel_text((unsigned long)addr)) {
|
|
|
|
+ pages[0] = vmalloc_to_page(addr);
|
|
|
|
+ pages[1] = vmalloc_to_page(addr + PAGE_SIZE);
|
|
} else {
|
|
} else {
|
|
- /*
|
|
|
|
- * modules are in vmalloc'ed memory, always writable.
|
|
|
|
- */
|
|
|
|
- local_irq_save(flags);
|
|
|
|
- memcpy(addr, opcode, len);
|
|
|
|
- local_irq_restore(flags);
|
|
|
|
|
|
+ pages[0] = virt_to_page(addr);
|
|
|
|
+ pages[1] = virt_to_page(addr + PAGE_SIZE);
|
|
}
|
|
}
|
|
|
|
+ BUG_ON(!pages[0]);
|
|
|
|
+ if (!pages[1])
|
|
|
|
+ nr_pages = 1;
|
|
|
|
+ vaddr = vmap(pages, nr_pages, VM_MAP, PAGE_KERNEL);
|
|
|
|
+ BUG_ON(!vaddr);
|
|
|
|
+ local_irq_save(flags);
|
|
|
|
+ memcpy(&vaddr[(unsigned long)addr & ~PAGE_MASK], opcode, len);
|
|
|
|
+ local_irq_restore(flags);
|
|
|
|
+ vunmap(vaddr);
|
|
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;
|
|
}
|
|
}
|