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