1*f06bfe3dSDeepak Gupta/* 2*f06bfe3dSDeepak Gupta * RISC-V translation routines for the Control-Flow Integrity Extension 3*f06bfe3dSDeepak Gupta * 4*f06bfe3dSDeepak Gupta * Copyright (c) 2024 Rivos Inc. 5*f06bfe3dSDeepak Gupta * 6*f06bfe3dSDeepak Gupta * This program is free software; you can redistribute it and/or modify it 7*f06bfe3dSDeepak Gupta * under the terms and conditions of the GNU General Public License, 8*f06bfe3dSDeepak Gupta * version 2 or later, as published by the Free Software Foundation. 9*f06bfe3dSDeepak Gupta * 10*f06bfe3dSDeepak Gupta * This program is distributed in the hope it will be useful, but WITHOUT 11*f06bfe3dSDeepak Gupta * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12*f06bfe3dSDeepak Gupta * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13*f06bfe3dSDeepak Gupta * more details. 14*f06bfe3dSDeepak Gupta * 15*f06bfe3dSDeepak Gupta * You should have received a copy of the GNU General Public License along with 16*f06bfe3dSDeepak Gupta * this program. If not, see <http://www.gnu.org/licenses/>. 17*f06bfe3dSDeepak Gupta */ 18*f06bfe3dSDeepak Guptastatic bool trans_sspopchk(DisasContext *ctx, arg_sspopchk *a) 19*f06bfe3dSDeepak Gupta{ 20*f06bfe3dSDeepak Gupta if (!ctx->bcfi_enabled) { 21*f06bfe3dSDeepak Gupta return false; 22*f06bfe3dSDeepak Gupta } 23*f06bfe3dSDeepak Gupta 24*f06bfe3dSDeepak Gupta TCGv addr = tcg_temp_new(); 25*f06bfe3dSDeepak Gupta TCGLabel *skip = gen_new_label(); 26*f06bfe3dSDeepak Gupta uint32_t tmp = (get_xl(ctx) == MXL_RV64) ? 8 : 4; 27*f06bfe3dSDeepak Gupta TCGv data = tcg_temp_new(); 28*f06bfe3dSDeepak Gupta tcg_gen_ld_tl(addr, tcg_env, offsetof(CPURISCVState, ssp)); 29*f06bfe3dSDeepak Gupta decode_save_opc(ctx, RISCV_UW2_ALWAYS_STORE_AMO); 30*f06bfe3dSDeepak Gupta tcg_gen_qemu_ld_tl(data, addr, SS_MMU_INDEX(ctx), 31*f06bfe3dSDeepak Gupta mxl_memop(ctx) | MO_ALIGN); 32*f06bfe3dSDeepak Gupta TCGv rs1 = get_gpr(ctx, a->rs1, EXT_NONE); 33*f06bfe3dSDeepak Gupta tcg_gen_brcond_tl(TCG_COND_EQ, data, rs1, skip); 34*f06bfe3dSDeepak Gupta tcg_gen_st_tl(tcg_constant_tl(RISCV_EXCP_SW_CHECK_BCFI_TVAL), 35*f06bfe3dSDeepak Gupta tcg_env, offsetof(CPURISCVState, sw_check_code)); 36*f06bfe3dSDeepak Gupta gen_helper_raise_exception(tcg_env, 37*f06bfe3dSDeepak Gupta tcg_constant_i32(RISCV_EXCP_SW_CHECK)); 38*f06bfe3dSDeepak Gupta gen_set_label(skip); 39*f06bfe3dSDeepak Gupta tcg_gen_addi_tl(addr, addr, tmp); 40*f06bfe3dSDeepak Gupta tcg_gen_st_tl(addr, tcg_env, offsetof(CPURISCVState, ssp)); 41*f06bfe3dSDeepak Gupta 42*f06bfe3dSDeepak Gupta return true; 43*f06bfe3dSDeepak Gupta} 44*f06bfe3dSDeepak Gupta 45*f06bfe3dSDeepak Guptastatic bool trans_sspush(DisasContext *ctx, arg_sspush *a) 46*f06bfe3dSDeepak Gupta{ 47*f06bfe3dSDeepak Gupta if (!ctx->bcfi_enabled) { 48*f06bfe3dSDeepak Gupta return false; 49*f06bfe3dSDeepak Gupta } 50*f06bfe3dSDeepak Gupta 51*f06bfe3dSDeepak Gupta TCGv addr = tcg_temp_new(); 52*f06bfe3dSDeepak Gupta int tmp = (get_xl(ctx) == MXL_RV64) ? -8 : -4; 53*f06bfe3dSDeepak Gupta TCGv data = get_gpr(ctx, a->rs2, EXT_NONE); 54*f06bfe3dSDeepak Gupta decode_save_opc(ctx, RISCV_UW2_ALWAYS_STORE_AMO); 55*f06bfe3dSDeepak Gupta tcg_gen_ld_tl(addr, tcg_env, offsetof(CPURISCVState, ssp)); 56*f06bfe3dSDeepak Gupta tcg_gen_addi_tl(addr, addr, tmp); 57*f06bfe3dSDeepak Gupta tcg_gen_qemu_st_tl(data, addr, SS_MMU_INDEX(ctx), 58*f06bfe3dSDeepak Gupta mxl_memop(ctx) | MO_ALIGN); 59*f06bfe3dSDeepak Gupta tcg_gen_st_tl(addr, tcg_env, offsetof(CPURISCVState, ssp)); 60*f06bfe3dSDeepak Gupta 61*f06bfe3dSDeepak Gupta return true; 62*f06bfe3dSDeepak Gupta} 63*f06bfe3dSDeepak Gupta 64*f06bfe3dSDeepak Guptastatic bool trans_ssrdp(DisasContext *ctx, arg_ssrdp *a) 65*f06bfe3dSDeepak Gupta{ 66*f06bfe3dSDeepak Gupta if (!ctx->bcfi_enabled || a->rd == 0) { 67*f06bfe3dSDeepak Gupta return false; 68*f06bfe3dSDeepak Gupta } 69*f06bfe3dSDeepak Gupta 70*f06bfe3dSDeepak Gupta TCGv dest = dest_gpr(ctx, a->rd); 71*f06bfe3dSDeepak Gupta tcg_gen_ld_tl(dest, tcg_env, offsetof(CPURISCVState, ssp)); 72*f06bfe3dSDeepak Gupta gen_set_gpr(ctx, a->rd, dest); 73*f06bfe3dSDeepak Gupta 74*f06bfe3dSDeepak Gupta return true; 75*f06bfe3dSDeepak Gupta} 76*f06bfe3dSDeepak Gupta 77*f06bfe3dSDeepak Guptastatic bool trans_ssamoswap_w(DisasContext *ctx, arg_amoswap_w *a) 78*f06bfe3dSDeepak Gupta{ 79*f06bfe3dSDeepak Gupta REQUIRE_A_OR_ZAAMO(ctx); 80*f06bfe3dSDeepak Gupta if (!ctx->bcfi_enabled) { 81*f06bfe3dSDeepak Gupta return false; 82*f06bfe3dSDeepak Gupta } 83*f06bfe3dSDeepak Gupta 84*f06bfe3dSDeepak Gupta TCGv dest = dest_gpr(ctx, a->rd); 85*f06bfe3dSDeepak Gupta TCGv src1, src2 = get_gpr(ctx, a->rs2, EXT_NONE); 86*f06bfe3dSDeepak Gupta 87*f06bfe3dSDeepak Gupta decode_save_opc(ctx, RISCV_UW2_ALWAYS_STORE_AMO); 88*f06bfe3dSDeepak Gupta src1 = get_address(ctx, a->rs1, 0); 89*f06bfe3dSDeepak Gupta 90*f06bfe3dSDeepak Gupta tcg_gen_atomic_xchg_tl(dest, src1, src2, SS_MMU_INDEX(ctx), 91*f06bfe3dSDeepak Gupta (MO_ALIGN | MO_TESL)); 92*f06bfe3dSDeepak Gupta gen_set_gpr(ctx, a->rd, dest); 93*f06bfe3dSDeepak Gupta return true; 94*f06bfe3dSDeepak Gupta} 95*f06bfe3dSDeepak Gupta 96*f06bfe3dSDeepak Guptastatic bool trans_ssamoswap_d(DisasContext *ctx, arg_amoswap_w *a) 97*f06bfe3dSDeepak Gupta{ 98*f06bfe3dSDeepak Gupta REQUIRE_64BIT(ctx); 99*f06bfe3dSDeepak Gupta REQUIRE_A_OR_ZAAMO(ctx); 100*f06bfe3dSDeepak Gupta if (!ctx->bcfi_enabled) { 101*f06bfe3dSDeepak Gupta return false; 102*f06bfe3dSDeepak Gupta } 103*f06bfe3dSDeepak Gupta 104*f06bfe3dSDeepak Gupta TCGv dest = dest_gpr(ctx, a->rd); 105*f06bfe3dSDeepak Gupta TCGv src1, src2 = get_gpr(ctx, a->rs2, EXT_NONE); 106*f06bfe3dSDeepak Gupta 107*f06bfe3dSDeepak Gupta decode_save_opc(ctx, RISCV_UW2_ALWAYS_STORE_AMO); 108*f06bfe3dSDeepak Gupta src1 = get_address(ctx, a->rs1, 0); 109*f06bfe3dSDeepak Gupta 110*f06bfe3dSDeepak Gupta tcg_gen_atomic_xchg_tl(dest, src1, src2, SS_MMU_INDEX(ctx), 111*f06bfe3dSDeepak Gupta (MO_ALIGN | MO_TESQ)); 112*f06bfe3dSDeepak Gupta gen_set_gpr(ctx, a->rd, dest); 113*f06bfe3dSDeepak Gupta return true; 114*f06bfe3dSDeepak Gupta} 115