2010-09-17 19:09:22 +04:00
/*
* 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 ) ) ;
} ;
2011-09-29 22:11:09 +04:00
static void __jump_label_transform ( struct jump_entry * entry ,
enum jump_label_type type ,
void * ( * poker ) ( void * , const void * , size_t ) )
2010-09-17 19:09:22 +04:00
{
union jump_code_union code ;
if ( type = = JUMP_LABEL_ENABLE ) {
code . jump = 0xe9 ;
code . offset = entry - > target -
( entry - > code + JUMP_LABEL_NOP_SIZE ) ;
} else
2011-04-19 02:19:51 +04:00
memcpy ( & code , ideal_nops [ NOP_ATOMIC5 ] , JUMP_LABEL_NOP_SIZE ) ;
2011-09-29 22:11:09 +04:00
( * poker ) ( ( void * ) entry - > code , & code , JUMP_LABEL_NOP_SIZE ) ;
}
void arch_jump_label_transform ( struct jump_entry * entry ,
enum jump_label_type type )
{
2010-09-17 19:09:22 +04:00
get_online_cpus ( ) ;
mutex_lock ( & text_mutex ) ;
2011-09-29 22:11:09 +04:00
__jump_label_transform ( entry , type , text_poke_smp ) ;
2010-09-17 19:09:22 +04:00
mutex_unlock ( & text_mutex ) ;
put_online_cpus ( ) ;
}
2011-12-06 20:27:29 +04:00
__init_or_module void arch_jump_label_transform_static ( struct jump_entry * entry ,
2011-09-29 22:11:09 +04:00
enum jump_label_type type )
{
__jump_label_transform ( entry , type , text_poke_early ) ;
}
2010-09-17 19:09:22 +04:00
# endif