mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-01-22 15:41:10 +00:00
target/riscv: Implement checks for hfence
Call the helper_hyp_tlb_flush() function on hfence instructions which will generate an illegal insruction execption if we don't have permission to flush the Hypervisor level TLBs. Backports commit 2761db5fc20943bbd606b6fd49640ac000398de6 from qemu
This commit is contained in:
parent
8eb8bc290f
commit
e1f49dc888
|
@ -5707,6 +5707,7 @@ riscv_symbols = (
|
||||||
'helper_fsqrt_s',
|
'helper_fsqrt_s',
|
||||||
'helper_fsub_d',
|
'helper_fsub_d',
|
||||||
'helper_fsub_s',
|
'helper_fsub_s',
|
||||||
|
'helper_hyp_tlb_flush',
|
||||||
'helper_mret',
|
'helper_mret',
|
||||||
'helper_tlb_flush',
|
'helper_tlb_flush',
|
||||||
'helper_set_rounding_mode',
|
'helper_set_rounding_mode',
|
||||||
|
|
|
@ -3458,6 +3458,7 @@
|
||||||
#define helper_fsqrt_s helper_fsqrt_s_riscv32
|
#define helper_fsqrt_s helper_fsqrt_s_riscv32
|
||||||
#define helper_fsub_d helper_fsub_d_riscv32
|
#define helper_fsub_d helper_fsub_d_riscv32
|
||||||
#define helper_fsub_s helper_fsub_s_riscv32
|
#define helper_fsub_s helper_fsub_s_riscv32
|
||||||
|
#define helper_hyp_tlb_flush helper_hyp_tlb_flush_riscv32
|
||||||
#define helper_mret helper_mret_riscv32
|
#define helper_mret helper_mret_riscv32
|
||||||
#define helper_tlb_flush helper_tlb_flush_riscv32
|
#define helper_tlb_flush helper_tlb_flush_riscv32
|
||||||
#define helper_set_rounding_mode helper_set_rounding_mode_riscv32
|
#define helper_set_rounding_mode helper_set_rounding_mode_riscv32
|
||||||
|
|
|
@ -3458,6 +3458,7 @@
|
||||||
#define helper_fsqrt_s helper_fsqrt_s_riscv64
|
#define helper_fsqrt_s helper_fsqrt_s_riscv64
|
||||||
#define helper_fsub_d helper_fsub_d_riscv64
|
#define helper_fsub_d helper_fsub_d_riscv64
|
||||||
#define helper_fsub_s helper_fsub_s_riscv64
|
#define helper_fsub_s helper_fsub_s_riscv64
|
||||||
|
#define helper_hyp_tlb_flush helper_hyp_tlb_flush_riscv64
|
||||||
#define helper_mret helper_mret_riscv64
|
#define helper_mret helper_mret_riscv64
|
||||||
#define helper_tlb_flush helper_tlb_flush_riscv64
|
#define helper_tlb_flush helper_tlb_flush_riscv64
|
||||||
#define helper_set_rounding_mode helper_set_rounding_mode_riscv64
|
#define helper_set_rounding_mode helper_set_rounding_mode_riscv64
|
||||||
|
|
|
@ -79,3 +79,8 @@ DEF_HELPER_2(mret, tl, env, tl)
|
||||||
DEF_HELPER_1(wfi, void, env)
|
DEF_HELPER_1(wfi, void, env)
|
||||||
DEF_HELPER_1(tlb_flush, void, env)
|
DEF_HELPER_1(tlb_flush, void, env)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Hypervisor functions */
|
||||||
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
DEF_HELPER_1(hyp_tlb_flush, void, env)
|
||||||
|
#endif
|
||||||
|
|
|
@ -18,40 +18,22 @@
|
||||||
|
|
||||||
static bool trans_hfence_gvma(DisasContext *ctx, arg_sfence_vma *a)
|
static bool trans_hfence_gvma(DisasContext *ctx, arg_sfence_vma *a)
|
||||||
{
|
{
|
||||||
|
REQUIRE_EXT(ctx, RVH);
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
||||||
if (has_ext(ctx, RVH)) {
|
gen_helper_hyp_tlb_flush(tcg_ctx, tcg_ctx->cpu_env);
|
||||||
/* Hpervisor extensions exist */
|
|
||||||
/*
|
|
||||||
* if (env->priv == PRV_M ||
|
|
||||||
* (env->priv == PRV_S &&
|
|
||||||
* !riscv_cpu_virt_enabled(env) &&
|
|
||||||
* get_field(ctx->mstatus_fs, MSTATUS_TVM))) {
|
|
||||||
*/
|
|
||||||
gen_helper_tlb_flush(tcg_ctx, tcg_ctx->cpu_env);
|
|
||||||
return true;
|
return true;
|
||||||
/* } */
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool trans_hfence_vvma(DisasContext *ctx, arg_sfence_vma *a)
|
static bool trans_hfence_vvma(DisasContext *ctx, arg_sfence_vma *a)
|
||||||
{
|
{
|
||||||
|
REQUIRE_EXT(ctx, RVH);
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
||||||
if (has_ext(ctx, RVH)) {
|
gen_helper_hyp_tlb_flush(tcg_ctx, tcg_ctx->cpu_env);
|
||||||
/* Hpervisor extensions exist */
|
|
||||||
/*
|
|
||||||
* if (env->priv == PRV_M ||
|
|
||||||
* (env->priv == PRV_S &&
|
|
||||||
* !riscv_cpu_virt_enabled(env) &&
|
|
||||||
* get_field(ctx->mstatus_fs, MSTATUS_TVM))) {
|
|
||||||
*/
|
|
||||||
gen_helper_tlb_flush(tcg_ctx, tcg_ctx->cpu_env);
|
|
||||||
return true;
|
return true;
|
||||||
/* } */
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,4 +193,17 @@ void helper_tlb_flush(CPURISCVState *env)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void helper_hyp_tlb_flush(CPURISCVState *env)
|
||||||
|
{
|
||||||
|
CPUState *cs = env_cpu(env);
|
||||||
|
|
||||||
|
if (env->priv == PRV_M ||
|
||||||
|
(env->priv == PRV_S && !riscv_cpu_virt_enabled(env))) {
|
||||||
|
tlb_flush(cs);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* !CONFIG_USER_ONLY */
|
#endif /* !CONFIG_USER_ONLY */
|
||||||
|
|
Loading…
Reference in a new issue