summaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/jump_label.c
diff options
context:
space:
mode:
authorJason Baron2010-09-17 17:09:22 +0200
committerSteven Rostedt2010-09-22 22:33:03 +0200
commitd9f5ab7b1c0a520867af389bab5d5fcdbd0e407e (patch)
tree23c9b85999b4340ec03ba0cef075b8ad73c4c994 /arch/x86/kernel/jump_label.c
parentjump label: Convert dynamic debug to use jump labels (diff)
downloadkernel-qcow2-linux-d9f5ab7b1c0a520867af389bab5d5fcdbd0e407e.tar.gz
kernel-qcow2-linux-d9f5ab7b1c0a520867af389bab5d5fcdbd0e407e.tar.xz
kernel-qcow2-linux-d9f5ab7b1c0a520867af389bab5d5fcdbd0e407e.zip
jump label: x86 support
add x86 support for jump label. I'm keeping this patch separate so its clear to arch maintainers what was required for x86 support this new feature. Hopefully, it wouldn't be too painful for other archs. Signed-off-by: Jason Baron <jbaron@redhat.com> LKML-Reference: <f838f49f40fbea0254036194be66dc48b598dcea.1284733808.git.jbaron@redhat.com> [ cleaned up some formatting ] Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'arch/x86/kernel/jump_label.c')
-rw-r--r--arch/x86/kernel/jump_label.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/arch/x86/kernel/jump_label.c b/arch/x86/kernel/jump_label.c
new file mode 100644
index 000000000000..961b6b30ba90
--- /dev/null
+++ b/arch/x86/kernel/jump_label.c
@@ -0,0 +1,50 @@
+/*
+ * jump label x86 support
+ *
+ * Copyright (C) 2009 Jason Baron <jbaron@redhat.com>
+ *
+ */
+#include <linux/jump_label.h>
+#include <linux/memory.h>
+#include <linux/uaccess.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/jhash.h>
+#include <linux/cpu.h>
+#include <asm/kprobes.h>
+#include <asm/alternative.h>
+
+#ifdef HAVE_JUMP_LABEL
+
+union jump_code_union {
+ char code[JUMP_LABEL_NOP_SIZE];
+ struct {
+ char jump;
+ int offset;
+ } __attribute__((packed));
+};
+
+void arch_jump_label_transform(struct jump_entry *entry,
+ enum jump_label_type type)
+{
+ union jump_code_union code;
+
+ if (type == JUMP_LABEL_ENABLE) {
+ code.jump = 0xe9;
+ code.offset = entry->target -
+ (entry->code + JUMP_LABEL_NOP_SIZE);
+ } else
+ memcpy(&code, ideal_nop5, JUMP_LABEL_NOP_SIZE);
+ get_online_cpus();
+ mutex_lock(&text_mutex);
+ text_poke_smp((void *)entry->code, &code, JUMP_LABEL_NOP_SIZE);
+ mutex_unlock(&text_mutex);
+ put_online_cpus();
+}
+
+void arch_jump_label_text_poke_early(jump_label_t addr)
+{
+ text_poke_early((void *)addr, ideal_nop5, JUMP_LABEL_NOP_SIZE);
+}
+
+#endif