f008a2d218
We should call decode_save_opc() for all relevant instructions which
can potentially generate a virtual instruction fault or a guest page
fault because generating transformed instruction upon guest page fault
expects opcode to be available. Without this, hypervisor will see
transformed instruction as zero in htinst CSR for guest MMIO emulation
which makes MMIO emulation in hypervisor slow and also breaks nested
virtualization.
Fixes: a9814e3e08
("target/riscv: Minimize the calls to decode_save_opc")
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-Id: <20230120125950.2246378-5-apatel@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
79 lines
2.1 KiB
C++
79 lines
2.1 KiB
C++
/*
|
|
* RISC-V translation routines for the Svinval Standard Instruction Set.
|
|
*
|
|
* Copyright (c) 2020-2022 PLCT lab
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms and conditions of the GNU General Public License,
|
|
* version 2 or later, as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with
|
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#define REQUIRE_SVINVAL(ctx) do { \
|
|
if (!ctx->cfg_ptr->ext_svinval) { \
|
|
return false; \
|
|
} \
|
|
} while (0)
|
|
|
|
static bool trans_sinval_vma(DisasContext *ctx, arg_sinval_vma *a)
|
|
{
|
|
REQUIRE_SVINVAL(ctx);
|
|
/* Do the same as sfence.vma currently */
|
|
REQUIRE_EXT(ctx, RVS);
|
|
#ifndef CONFIG_USER_ONLY
|
|
decode_save_opc(ctx);
|
|
gen_helper_tlb_flush(cpu_env);
|
|
return true;
|
|
#endif
|
|
return false;
|
|
}
|
|
|
|
static bool trans_sfence_w_inval(DisasContext *ctx, arg_sfence_w_inval *a)
|
|
{
|
|
REQUIRE_SVINVAL(ctx);
|
|
REQUIRE_EXT(ctx, RVS);
|
|
/* Do nothing currently */
|
|
return true;
|
|
}
|
|
|
|
static bool trans_sfence_inval_ir(DisasContext *ctx, arg_sfence_inval_ir *a)
|
|
{
|
|
REQUIRE_SVINVAL(ctx);
|
|
REQUIRE_EXT(ctx, RVS);
|
|
/* Do nothing currently */
|
|
return true;
|
|
}
|
|
|
|
static bool trans_hinval_vvma(DisasContext *ctx, arg_hinval_vvma *a)
|
|
{
|
|
REQUIRE_SVINVAL(ctx);
|
|
/* Do the same as hfence.vvma currently */
|
|
REQUIRE_EXT(ctx, RVH);
|
|
#ifndef CONFIG_USER_ONLY
|
|
decode_save_opc(ctx);
|
|
gen_helper_hyp_tlb_flush(cpu_env);
|
|
return true;
|
|
#endif
|
|
return false;
|
|
}
|
|
|
|
static bool trans_hinval_gvma(DisasContext *ctx, arg_hinval_gvma *a)
|
|
{
|
|
REQUIRE_SVINVAL(ctx);
|
|
/* Do the same as hfence.gvma currently */
|
|
REQUIRE_EXT(ctx, RVH);
|
|
#ifndef CONFIG_USER_ONLY
|
|
decode_save_opc(ctx);
|
|
gen_helper_hyp_gvma_tlb_flush(cpu_env);
|
|
return true;
|
|
#endif
|
|
return false;
|
|
}
|