Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b7b66baa authored by Mathieu Desnoyers's avatar Mathieu Desnoyers Committed by Ingo Molnar
Browse files

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: default avatarMathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 8b132ecb
Loading
Loading
Loading
Loading
+18 −20
Original line number Original line Diff line number Diff line
@@ -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;
}
}