From patchwork Wed Aug 21 21:50:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Deepak Gupta X-Patchwork-Id: 13772125 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 48267C5320E for ; Wed, 21 Aug 2024 21:52:13 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sgtDw-0005fN-0x; Wed, 21 Aug 2024 17:50:36 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sgtDu-0005Xu-7v for qemu-devel@nongnu.org; Wed, 21 Aug 2024 17:50:34 -0400 Received: from mail-pl1-x62a.google.com ([2607:f8b0:4864:20::62a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1sgtDs-00087R-51 for qemu-devel@nongnu.org; Wed, 21 Aug 2024 17:50:33 -0400 Received: by mail-pl1-x62a.google.com with SMTP id d9443c01a7336-201fbd0d7c2so1684735ad.0 for ; Wed, 21 Aug 2024 14:50:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1724277031; x=1724881831; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=wDMdzByYVmU7qdgZ8LR0QMdovXfAZYZ4IKP1EgsyAp4=; b=WiowBBR5sl2UPVWy24xC0fRC10df6MS6KK6YsNaCceO6BOvhwRSYONGTf42uJMaP4G 3Ewc9oCc7KcoxLhkdtAWZOa0cPg/6dG9o/jw07yhgLIhdEpIm0g/eEEBhHkRkj7LNO+P oVjKHtCrB6m6DiCTVaNnY5c0Yl7nM26XPTRxddH1U48Fpj9N8Cciyvl1Vv+OJ2Q6PZJc WYHr66xESPhU8WIL7pYH/UEZbqj2Qf9aKa40cAlh9vend/s5VkXcJg5ws9YbnxjZQ7ai dexxNnRVPacn/XXHkiOYE0QyNIFVJAF2/WLW+uPi/4JLrG1Ro9mtQnzB04uaBeE6cryk 7RZg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724277031; x=1724881831; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=wDMdzByYVmU7qdgZ8LR0QMdovXfAZYZ4IKP1EgsyAp4=; b=Kc6VUc7gBTZGSSEOvVuMl2mg5obupq2kGVmhT/sdu6vj9o+n3TUvkqpC8T0tODed+/ wSWutCRBrvzD07B/Vc//wCN0dyCueJ/7ZA9ea2GEGAORD94YPPn+m8EGRza5PkFTVdrA ueGphKEMlg6SzGstFiyu4uue7Er3fVSFUr/xM4qemo0wVYBBnKz3HJfkTb32wjd1oFce Plpx3DTBt+CEQUvqOBsyyRmBSxwun+js/Og+vyedsyOJYfkOxrAxpUxTrprd2xiWtmzd NbaJJnjXYQurgHGKIfyrotuY4Y8mGUPNqGr/BBWyWB2faBTicj8U3RGaTCn6EZr2Y7RF 1dAQ== X-Forwarded-Encrypted: i=1; AJvYcCU737ZvdRlXQSC3eY3fzRBXYAEL0oAiK9ks0rLzG3oY6b4c/21dMOQj8QM3bGWjq9nrs2sCvlF7KI9d@nongnu.org X-Gm-Message-State: AOJu0YxefTBStSUg0MpmdtC5LW/TrVWsc4+lF7FjDM1LlnmEBkCfndDy OQSaiA5zQZ1DWK1WFdeJxlcfPX8O3qa1kZDCypFazESmMnvDZuvgKcm77gMkYJQ= X-Google-Smtp-Source: AGHT+IFvH/JEcN3oF85VihL4Pobug3LZ5ssZFTLlPKL8gxgXkKKGj84cZ9qyWxbJptrQnH3I2IHIgA== X-Received: by 2002:a17:902:e887:b0:202:3e52:e124 with SMTP id d9443c01a7336-20367d5c5f6mr39495265ad.31.1724277030738; Wed, 21 Aug 2024 14:50:30 -0700 (PDT) Received: from debug.ba.rivosinc.com ([64.71.180.162]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-203859ef0fdsm586345ad.248.2024.08.21.14.50.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 21 Aug 2024 14:50:30 -0700 (PDT) From: Deepak Gupta To: qemu-riscv@nongnu.org, qemu-devel@nongnu.org Cc: palmer@dabbelt.com, Alistair.Francis@wdc.com, bmeng.cn@gmail.com, liwei1518@gmail.com, dbarboza@ventanamicro.com, zhiwei_liu@linux.alibaba.com, jim.shu@sifive.com, andy.chiu@sifive.com, kito.cheng@sifive.com, Deepak Gupta Subject: [PATCH v6 09/16] target/riscv: introduce ssp and enabling controls for zicfiss Date: Wed, 21 Aug 2024 14:50:07 -0700 Message-ID: <20240821215014.3859190-10-debug@rivosinc.com> X-Mailer: git-send-email 2.45.0 In-Reply-To: <20240821215014.3859190-1-debug@rivosinc.com> References: <20240821215014.3859190-1-debug@rivosinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::62a; envelope-from=debug@rivosinc.com; helo=mail-pl1-x62a.google.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org zicfiss introduces a new state ssp ("shadow stack register") in cpu. ssp is expressed as a new unprivileged csr (CSR_SSP=0x11) and holds virtual address for shadow stack as programmed by software. Shadow stack (for each mode) is enabled via bit3 in *envcfg CSRs. Shadow stack can be enabled for a mode only if it's higher privileged mode had it enabled for itself. M mode doesn't need enabling control, it's always available if extension is available on cpu. This patch also implements helper bcfi function which determines if bcfi is enabled at current privilege or not. qemu-user also gets field `ubcfien` indicating whether qemu user has shadow stack enabled or not. Adds ssp to migration state as well. Signed-off-by: Deepak Gupta Co-developed-by: Jim Shu Co-developed-by: Andy Chiu Reviewed-by: Richard Henderson --- target/riscv/cpu.c | 5 ++++ target/riscv/cpu.h | 4 +++ target/riscv/cpu_bits.h | 6 +++++ target/riscv/cpu_helper.c | 25 +++++++++++++++++++ target/riscv/csr.c | 52 +++++++++++++++++++++++++++++++++++++++ target/riscv/machine.c | 19 ++++++++++++++ 6 files changed, 111 insertions(+) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 10a2a32345..76f1edd15a 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -998,6 +998,9 @@ static void riscv_cpu_reset_hold(Object *obj, ResetType type) /* on reset elp is clear */ env->elp = false; + /* on reset ssp is set to 0 */ + env->ssp = 0; + /* * Bits 10, 6, 2 and 12 of mideleg are read only 1 when the Hypervisor * extension is enabled. @@ -1026,6 +1029,8 @@ static void riscv_cpu_reset_hold(Object *obj, ResetType type) #ifdef CONFIG_USER_ONLY /* qemu-user for riscv, fcfi is off by default */ env->ufcfien = false; + /* qemu-user for riscv, bcfi is off by default */ + env->ubcfien = false; #endif #ifndef CONFIG_USER_ONLY diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index edf540339a..5a57099d59 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -224,11 +224,14 @@ struct CPUArchState { /* elp state for zicfilp extension */ bool elp; + /* shadow stack register for zicfiss extension */ + target_ulong ssp; /* sw check code for sw check exception */ target_ulong sw_check_code; #ifdef CONFIG_USER_ONLY uint32_t elf_flags; bool ufcfien; + bool ubcfien; #endif #ifndef CONFIG_USER_ONLY @@ -534,6 +537,7 @@ bool riscv_cpu_vector_enabled(CPURISCVState *env); void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable); int riscv_env_mmu_index(CPURISCVState *env, bool ifetch); bool cpu_get_fcfien(CPURISCVState *env); +bool cpu_get_bcfien(CPURISCVState *env); G_NORETURN void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr, MMUAccessType access_type, int mmu_idx, uintptr_t retaddr); diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index 900769ce60..48ce24dc32 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -34,6 +34,9 @@ /* Control and Status Registers */ +/* zicfiss user ssp csr */ +#define CSR_SSP 0x011 + /* User Trap Setup */ #define CSR_USTATUS 0x000 #define CSR_UIE 0x004 @@ -754,6 +757,7 @@ typedef enum RISCVException { /* Execution environment configuration bits */ #define MENVCFG_FIOM BIT(0) #define MENVCFG_LPE BIT(2) /* zicfilp */ +#define MENVCFG_SSE BIT(3) /* zicfiss */ #define MENVCFG_CBIE (3UL << 4) #define MENVCFG_CBCFE BIT(6) #define MENVCFG_CBZE BIT(7) @@ -768,12 +772,14 @@ typedef enum RISCVException { #define SENVCFG_FIOM MENVCFG_FIOM #define SENVCFG_LPE MENVCFG_LPE +#define SENVCFG_SSE MENVCFG_SSE #define SENVCFG_CBIE MENVCFG_CBIE #define SENVCFG_CBCFE MENVCFG_CBCFE #define SENVCFG_CBZE MENVCFG_CBZE #define HENVCFG_FIOM MENVCFG_FIOM #define HENVCFG_LPE MENVCFG_LPE +#define HENVCFG_SSE MENVCFG_SSE #define HENVCFG_CBIE MENVCFG_CBIE #define HENVCFG_CBCFE MENVCFG_CBCFE #define HENVCFG_CBZE MENVCFG_CBZE diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 3a56bea8b9..96571177ef 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -92,6 +92,31 @@ bool cpu_get_fcfien(CPURISCVState *env) #endif } +bool cpu_get_bcfien(CPURISCVState *env) +{ + /* no cfi extension, return false */ + if (!env_archcpu(env)->cfg.ext_zicfiss) { + return false; + } +#ifdef CONFIG_USER_ONLY + return env->ubcfien; +#else + switch (env->priv) { + case PRV_U: + return env->senvcfg & SENVCFG_SSE; + case PRV_S: + if (env->virt_enabled) { + return env->henvcfg & HENVCFG_SSE; + } + return env->menvcfg & MENVCFG_SSE; + case PRV_M: /* M-mode shadow stack is always on if hart implements */ + return true; + default: + g_assert_not_reached(); + } +#endif +} + void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, uint64_t *cs_base, uint32_t *pflags) { diff --git a/target/riscv/csr.c b/target/riscv/csr.c index a5a969a377..ec04b2b32b 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -185,6 +185,25 @@ static RISCVException zcmt(CPURISCVState *env, int csrno) return RISCV_EXCP_NONE; } +static RISCVException cfi_ss(CPURISCVState *env, int csrno) +{ + if (!env_archcpu(env)->cfg.ext_zicfiss) { + return RISCV_EXCP_ILLEGAL_INST; + } + + /* if bcfi not active for current env, access to csr is illegal */ + if (!cpu_get_bcfien(env)) { +#if !defined(CONFIG_USER_ONLY) + if (env->debugger) { + return RISCV_EXCP_NONE; + } +#endif + return RISCV_EXCP_ILLEGAL_INST; + } + + return RISCV_EXCP_NONE; +} + #if !defined(CONFIG_USER_ONLY) static RISCVException mctr(CPURISCVState *env, int csrno) { @@ -596,6 +615,19 @@ static RISCVException seed(CPURISCVState *env, int csrno) #endif } +/* zicfiss CSR_SSP read and write */ +static int read_ssp(CPURISCVState *env, int csrno, target_ulong *val) +{ + *val = env->ssp; + return RISCV_EXCP_NONE; +} + +static int write_ssp(CPURISCVState *env, int csrno, target_ulong val) +{ + env->ssp = val; + return RISCV_EXCP_NONE; +} + /* User Floating-Point CSRs */ static RISCVException read_fflags(CPURISCVState *env, int csrno, target_ulong *val) @@ -2111,6 +2143,10 @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno, if (env_archcpu(env)->cfg.ext_zicfilp) { mask |= MENVCFG_LPE; } + + if (env_archcpu(env)->cfg.ext_zicfiss) { + mask |= MENVCFG_SSE; + } } env->menvcfg = (env->menvcfg & ~mask) | (val & mask); @@ -2167,6 +2203,13 @@ static RISCVException write_senvcfg(CPURISCVState *env, int csrno, mask |= SENVCFG_LPE; } + /* Higher mode SSE must be ON for next-less mode SSE to be ON */ + if (env_archcpu(env)->cfg.ext_zicfiss && + get_field(env->menvcfg, MENVCFG_SSE) && + (env->virt_enabled ? get_field(env->henvcfg, HENVCFG_SSE) : true)) { + mask |= SENVCFG_SSE; + } + env->senvcfg = (env->senvcfg & ~mask) | (val & mask); return RISCV_EXCP_NONE; } @@ -2208,6 +2251,12 @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno, if (env_archcpu(env)->cfg.ext_zicfilp) { mask |= HENVCFG_LPE; } + + /* H can light up SSE for VS only if HS had it from menvcfg */ + if (env_archcpu(env)->cfg.ext_zicfiss && + get_field(env->menvcfg, MENVCFG_SSE)) { + mask |= HENVCFG_SSE; + } } env->henvcfg = (env->henvcfg & ~mask) | (val & mask); @@ -4663,6 +4712,9 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { /* Zcmt Extension */ [CSR_JVT] = {"jvt", zcmt, read_jvt, write_jvt}, + /* zicfiss Extension, shadow stack register */ + [CSR_SSP] = { "ssp", cfi_ss, read_ssp, write_ssp }, + #if !defined(CONFIG_USER_ONLY) /* Machine Timers and Counters */ [CSR_MCYCLE] = { "mcycle", any, read_hpmcounter, diff --git a/target/riscv/machine.c b/target/riscv/machine.c index 873957c4ab..84d5ecf436 100644 --- a/target/riscv/machine.c +++ b/target/riscv/machine.c @@ -369,6 +369,24 @@ static const VMStateDescription vmstate_elp = { } }; +static bool ssp_needed(void *opaque) +{ + RISCVCPU *cpu = opaque; + + return cpu->cfg.ext_zicfiss; +} + +static const VMStateDescription vmstate_ssp = { + .name = "cpu/ssp", + .version_id = 1, + .minimum_version_id = 1, + .needed = ssp_needed, + .fields = (const VMStateField[]) { + VMSTATE_UINTTL(env.ssp, RISCVCPU), + VMSTATE_END_OF_LIST() + } +}; + const VMStateDescription vmstate_riscv_cpu = { .name = "cpu", .version_id = 10, @@ -442,6 +460,7 @@ const VMStateDescription vmstate_riscv_cpu = { &vmstate_smstateen, &vmstate_jvt, &vmstate_elp, + &vmstate_ssp, NULL } };