@ -162,6 +162,7 @@ static TCGContext **tcg_ctxs;
static unsigned int n_tcg_ctxs ;
TCGv_env cpu_env = 0 ;
void * tcg_code_gen_epilogue ;
uintptr_t tcg_splitwx_diff ;
# ifndef CONFIG_TCG_INTERPRETER
tcg_prologue_fn * tcg_qemu_tb_exec ;
@ -406,8 +407,9 @@ static void tcg_region_trees_init(void)
}
}
static struct tcg_region_tree * tc_ptr_to_region_tree ( void * p )
static struct tcg_region_tree * tc_ptr_to_region_tree ( const void * c p)
{
void * p = tcg_splitwx_to_rw ( cp ) ;
size_t region_idx ;
if ( p < region . start_aligned ) {
@ -701,6 +703,7 @@ void tcg_region_init(void)
size_t region_size ;
size_t n_regions ;
size_t i ;
uintptr_t splitwx_diff ;
n_regions = tcg_n_regions ( ) ;
@ -731,6 +734,7 @@ void tcg_region_init(void)
region . end - = page_size ;
/* set guard pages */
splitwx_diff = tcg_splitwx_diff ;
for ( i = 0 ; i < region . n ; i + + ) {
void * start , * end ;
int rc ;
@ -738,6 +742,10 @@ void tcg_region_init(void)
tcg_region_bounds ( i , & start , & end ) ;
rc = qemu_mprotect_none ( end , page_size ) ;
g_assert ( ! rc ) ;
if ( splitwx_diff ) {
rc = qemu_mprotect_none ( end + splitwx_diff , page_size ) ;
g_assert ( ! rc ) ;
}
}
tcg_region_trees_init ( ) ;
@ -752,6 +760,29 @@ void tcg_region_init(void)
# endif
}
# ifdef CONFIG_DEBUG_TCG
const void * tcg_splitwx_to_rx ( void * rw )
{
/* Pass NULL pointers unchanged. */
if ( rw ) {
g_assert ( in_code_gen_buffer ( rw ) ) ;
rw + = tcg_splitwx_diff ;
}
return rw ;
}
void * tcg_splitwx_to_rw ( const void * rx )
{
/* Pass NULL pointers unchanged. */
if ( rx ) {
rx - = tcg_splitwx_diff ;
/* Assert that we end with a pointer in the rw region. */
g_assert ( in_code_gen_buffer ( rx ) ) ;
}
return ( void * ) rx ;
}
# endif /* CONFIG_DEBUG_TCG */
static void alloc_tcg_plugin_context ( TCGContext * s )
{
# ifdef CONFIG_PLUGIN
@ -1061,8 +1092,15 @@ void tcg_prologue_init(TCGContext *s)
s - > code_buf = buf0 ;
s - > data_gen_ptr = NULL ;
/*
* The region trees are not yet configured , but tcg_splitwx_to_rx
* needs the bounds for an assert .
*/
region . start = buf0 ;
region . end = buf0 + total_size ;
# ifndef CONFIG_TCG_INTERPRETER
tcg_qemu_tb_exec = ( tcg_prologue_fn * ) buf0 ;
tcg_qemu_tb_exec = ( tcg_prologue_fn * ) tcg_splitwx_to_rx ( buf0 ) ;
# endif
/* Compute a high-water mark, at which we voluntarily flush the buffer
@ -1087,7 +1125,7 @@ void tcg_prologue_init(TCGContext *s)
buf1 = s - > code_ptr ;
# ifndef CONFIG_TCG_INTERPRETER
flush_idcache_range ( ( uintptr_t ) buf0 , ( uintptr_t ) buf0 ,
flush_idcache_range ( ( uintptr_t ) tcg_splitwx_to_rx ( buf0 ) , ( uintptr_t ) buf0 ,
tcg_ptr_byte_diff ( buf1 , buf0 ) ) ;
# endif
@ -4231,8 +4269,13 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
tcg_reg_alloc_start ( s ) ;
s - > code_buf = tb - > tc . ptr ;
s - > code_ptr = tb - > tc . ptr ;
/*
* Reset the buffer pointers when restarting after overflow .
* TODO : Move this into translate - all . c with the rest of the
* buffer management . Having only this done here is confusing .
*/
s - > code_buf = tcg_splitwx_to_rw ( tb - > tc . ptr ) ;
s - > code_ptr = s - > code_buf ;
# ifdef TCG_TARGET_NEED_LDST_LABELS
QSIMPLEQ_INIT ( & s - > ldst_labels ) ;
@ -4337,7 +4380,8 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
# ifndef CONFIG_TCG_INTERPRETER
/* flush instruction cache */
flush_idcache_range ( ( uintptr_t ) s - > code_buf , ( uintptr_t ) s - > code_buf ,
flush_idcache_range ( ( uintptr_t ) tcg_splitwx_to_rx ( s - > code_buf ) ,
( uintptr_t ) s - > code_buf ,
tcg_ptr_byte_diff ( s - > code_ptr , s - > code_buf ) ) ;
# endif