linux/arch/tile/kernel/jump_label.c
<<
>>
Prefs
   1/*
   2 * Copyright 2015 Tilera Corporation. All Rights Reserved.
   3 *
   4 *   This program is free software; you can redistribute it and/or
   5 *   modify it under the terms of the GNU General Public License
   6 *   as published by the Free Software Foundation, version 2.
   7 *
   8 *   This program is distributed in the hope that it will be useful, but
   9 *   WITHOUT ANY WARRANTY; without even the implied warranty of
  10 *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
  11 *   NON INFRINGEMENT.  See the GNU General Public License for
  12 *   more details.
  13 *
  14 * jump label TILE-Gx support
  15 */
  16
  17#include <linux/jump_label.h>
  18#include <linux/memory.h>
  19#include <linux/module.h>
  20#include <linux/mutex.h>
  21#include <linux/cpu.h>
  22
  23#include <asm/cacheflush.h>
  24#include <asm/insn.h>
  25
  26#ifdef HAVE_JUMP_LABEL
  27
  28static void __jump_label_transform(struct jump_entry *e,
  29                                   enum jump_label_type type)
  30{
  31        tilegx_bundle_bits opcode;
  32        /* Operate on writable kernel text mapping. */
  33        unsigned long pc_wr = ktext_writable_addr(e->code);
  34
  35        if (type == JUMP_LABEL_JMP)
  36                opcode = tilegx_gen_branch(e->code, e->target, false);
  37        else
  38                opcode = NOP();
  39
  40        *(tilegx_bundle_bits *)pc_wr = opcode;
  41        /* Make sure that above mem writes were issued towards the memory. */
  42        smp_wmb();
  43}
  44
  45void arch_jump_label_transform(struct jump_entry *e,
  46                                enum jump_label_type type)
  47{
  48        mutex_lock(&text_mutex);
  49
  50        __jump_label_transform(e, type);
  51        flush_icache_range(e->code, e->code + sizeof(tilegx_bundle_bits));
  52
  53        mutex_unlock(&text_mutex);
  54}
  55
  56__init_or_module void arch_jump_label_transform_static(struct jump_entry *e,
  57                                                enum jump_label_type type)
  58{
  59        __jump_label_transform(e, type);
  60}
  61
  62#endif /* HAVE_JUMP_LABEL */
  63