linux/arch/x86/kernel/jump_label.c
<<
>>
Prefs
   1/*
   2 * jump label x86 support
   3 *
   4 * Copyright (C) 2009 Jason Baron <jbaron@redhat.com>
   5 *
   6 */
   7#include <linux/jump_label.h>
   8#include <linux/memory.h>
   9#include <linux/uaccess.h>
  10#include <linux/module.h>
  11#include <linux/list.h>
  12#include <linux/jhash.h>
  13#include <linux/cpu.h>
  14#include <asm/kprobes.h>
  15#include <asm/alternative.h>
  16
  17#ifdef HAVE_JUMP_LABEL
  18
  19union jump_code_union {
  20        char code[JUMP_LABEL_NOP_SIZE];
  21        struct {
  22                char jump;
  23                int offset;
  24        } __attribute__((packed));
  25};
  26
  27static void __jump_label_transform(struct jump_entry *entry,
  28                                   enum jump_label_type type,
  29                                   void *(*poker)(void *, const void *, size_t))
  30{
  31        union jump_code_union code;
  32
  33        if (type == JUMP_LABEL_ENABLE) {
  34                code.jump = 0xe9;
  35                code.offset = entry->target -
  36                                (entry->code + JUMP_LABEL_NOP_SIZE);
  37        } else
  38                memcpy(&code, ideal_nops[NOP_ATOMIC5], JUMP_LABEL_NOP_SIZE);
  39
  40        (*poker)((void *)entry->code, &code, JUMP_LABEL_NOP_SIZE);
  41}
  42
  43void arch_jump_label_transform(struct jump_entry *entry,
  44                               enum jump_label_type type)
  45{
  46        get_online_cpus();
  47        mutex_lock(&text_mutex);
  48        __jump_label_transform(entry, type, text_poke_smp);
  49        mutex_unlock(&text_mutex);
  50        put_online_cpus();
  51}
  52
  53__init_or_module void arch_jump_label_transform_static(struct jump_entry *entry,
  54                                      enum jump_label_type type)
  55{
  56        __jump_label_transform(entry, type, text_poke_early);
  57}
  58
  59#endif
  60