From patchwork Thu Feb 9 06:29:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Deepak Gupta X-Patchwork-Id: 1739813 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=rivosinc-com.20210112.gappssmtp.com header.i=@rivosinc-com.20210112.gappssmtp.com header.a=rsa-sha256 header.s=20210112 header.b=7BQbWEn1; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4PC6TT3xQyz23jH for ; Thu, 9 Feb 2023 17:31:41 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pQ0SP-0007hu-9h; Thu, 09 Feb 2023 01:30:57 -0500 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 1pQ0Rv-0007X9-SO for qemu-devel@nongnu.org; Thu, 09 Feb 2023 01:30:30 -0500 Received: from mail-pg1-x533.google.com ([2607:f8b0:4864:20::533]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pQ0Rt-0000jX-7q for qemu-devel@nongnu.org; Thu, 09 Feb 2023 01:30:27 -0500 Received: by mail-pg1-x533.google.com with SMTP id 24so936730pgt.7 for ; Wed, 08 Feb 2023 22:30:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20210112.gappssmtp.com; s=20210112; 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=7CUYidC2PYJ4aSSo65h6OAHrCirLGNVfJL1zZ8fOzVI=; b=7BQbWEn1wCe3gUdWK6JN37gipvc3+DmocKKeWMl154ufeIcidO5gV5yiVej/OU1+14 hamdOlJnPXcac5tDsPzwNfPFpeuiQgu2icxyqpegPXRMHm0+xSGbIqKy4UWS9eP89VLN beiMB9e5AfJ6MPuRs5WVTz8cBNcNbS4KcNjb+J/+TkIr/Cqa8mS9fJBZPtvy02P3Az/a dCFcYhdkFWfY6xf1tV00IHL9Bj61aKjHPiXVTrgRSVEPR8LKE8vHiZO/vSAzQKww2P0b ZSM1J8U/h2yxGXYdMfgzroLZrUC46m7lLbF33bnkT9AzCcg8OMuVy+OUrcWhL0Y3SF1B YMyQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=7CUYidC2PYJ4aSSo65h6OAHrCirLGNVfJL1zZ8fOzVI=; b=w44X1MVN/UlZ+ZPtFTmdYLxOZS0p+vatb4vu04OL8FADBsA5g/n3k6qb+Ze5JgP6f/ ntbX1JZLZMezPIh9Y3vNo1qt9jmA1VdcztiA2GSe2fuYp78w9uKJPwP+6FXt9Holotac BS2HfQAM7sVd1ZhfnmBd1um/e4qslNqNsZKL8rhn0TxTqV7K6dQEGWCsqsSfToOdqcBY YHJ3OcQx6TK6fYRKnpxUcMxjsMur9Ik5HPKae1lBltJE8ErKD/0OzAvx+qARQl5kgUDK FfTfV25yidlcGrSgQEKHtYnxv1J58lFDxMjwDeVGNFypVnLg6VMtaPjs755QpSRoPzB6 5VrQ== X-Gm-Message-State: AO0yUKXr/y3G25Bca03e0RcH5Y//EPFsANKJLMbdV9YNZhP/mp25AZ/n WcVX+8HT7QETm9HJLdhUvtcihfBD5JeNP0JO X-Google-Smtp-Source: AK7set87I0ZuFubonTAGYosOcrg57ytRhJJ5Hma2/SaQmlrZhT/5tH998GfrR8DmwLGgoagdeOShjw== X-Received: by 2002:a62:2707:0:b0:5a8:4bf2:1d51 with SMTP id n7-20020a622707000000b005a84bf21d51mr3011034pfn.15.1675924223337; Wed, 08 Feb 2023 22:30:23 -0800 (PST) Received: from debug.ba.rivosinc.com ([66.220.2.162]) by smtp.gmail.com with ESMTPSA id u15-20020aa7848f000000b00593c434b1b8sm543649pfn.48.2023.02.08.22.30.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 08 Feb 2023 22:30:22 -0800 (PST) From: Deepak Gupta To: qemu-devel@nongnu.org, Palmer Dabbelt , Alistair Francis , Bin Meng Cc: Deepak Gupta , Kip Walker , qemu-riscv@nongnu.org Subject: [PATCH v1 RFC Zisslpcfi 1/9] target/riscv: adding zimops and zisslpcfi extension to RISCV cpu config Date: Wed, 8 Feb 2023 22:29:39 -0800 Message-Id: <20230209062947.3585481-2-debug@rivosinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230209062947.3585481-1-debug@rivosinc.com> References: <20230209062947.3585481-1-debug@rivosinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::533; envelope-from=debug@rivosinc.com; helo=mail-pg1-x533.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 autolearn=unavailable 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+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Introducing riscv `zisslpcfi` extension to riscv target. `zisslpcfi` extension provides hardware assistance to riscv hart to enable control flow integrity (CFI) for software. `zisslpcfi` extension expects hart to implement `zimops`. `zimops` stands for "unprivileged integer maybe operations". `zimops` carve out certain reserved opcodes encodings from integer spec to "may be operations" encodings. `zimops` opcode encodings simply move 0 to rd. `zisslpcfi` claims some of the `zimops` encodings and use them for shadow stack management or indirect branch tracking. Any future extension can also claim `zimops` encodings. This patch also adds a dependency check for `zimops` to be enabled if `zisslpcfi` is enabled on the hart. Signed-off-by: Deepak Gupta Signed-off-by: Kip Walker --- target/riscv/cpu.c | 13 +++++++++++++ target/riscv/cpu.h | 2 ++ 2 files changed, 15 insertions(+) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index cc75ca7667..6b4e90eb91 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -110,6 +110,8 @@ static const struct isa_ext_data isa_edata_arr[] = { ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot), ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt), ISA_EXT_DATA_ENTRY(xventanacondops, true, PRIV_VERSION_1_12_0, ext_XVentanaCondOps), + ISA_EXT_DATA_ENTRY(zimops, true, PRIV_VERSION_1_12_0, ext_zimops), + ISA_EXT_DATA_ENTRY(zisslpcfi, true, PRIV_VERSION_1_12_0, ext_cfi), }; static bool isa_ext_is_enabled(RISCVCPU *cpu, @@ -792,6 +794,11 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) return; } + if (cpu->cfg.ext_cfi && !cpu->cfg.ext_zimops) { + error_setg(errp, "Zisslpcfi extension requires Zimops extension"); + return; + } + /* Set the ISA extensions, checks should have happened above */ if (cpu->cfg.ext_zdinx || cpu->cfg.ext_zhinx || cpu->cfg.ext_zhinxmin) { @@ -1102,6 +1109,12 @@ static Property riscv_cpu_properties[] = { #ifndef CONFIG_USER_ONLY DEFINE_PROP_UINT64("resetvec", RISCVCPU, env.resetvec, DEFAULT_RSTVEC), #endif + /* + * Zisslpcfi CFI extension, Zisslpcfi implicitly means Zimops is + * implemented + */ + DEFINE_PROP_BOOL("zisslpcfi", RISCVCPU, cfg.ext_cfi, true), + DEFINE_PROP_BOOL("zimops", RISCVCPU, cfg.ext_zimops, true), DEFINE_PROP_BOOL("short-isa-string", RISCVCPU, cfg.short_isa_string, false), diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index f5609b62a2..9a923760b2 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -471,6 +471,8 @@ struct RISCVCPUConfig { uint32_t mvendorid; uint64_t marchid; uint64_t mimpid; + bool ext_zimops; + bool ext_cfi; /* Vendor-specific custom extensions */ bool ext_XVentanaCondOps; From patchwork Thu Feb 9 06:29:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Deepak Gupta X-Patchwork-Id: 1739818 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=rivosinc-com.20210112.gappssmtp.com header.i=@rivosinc-com.20210112.gappssmtp.com header.a=rsa-sha256 header.s=20210112 header.b=wp7Yab73; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4PC6V24D9Wz23jH for ; Thu, 9 Feb 2023 17:32:10 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pQ0SS-0007ln-2J; Thu, 09 Feb 2023 01:31:00 -0500 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 1pQ0Rw-0007XF-8x for qemu-devel@nongnu.org; Thu, 09 Feb 2023 01:30:30 -0500 Received: from mail-pg1-x530.google.com ([2607:f8b0:4864:20::530]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pQ0Ru-0000lA-Co for qemu-devel@nongnu.org; Thu, 09 Feb 2023 01:30:27 -0500 Received: by mail-pg1-x530.google.com with SMTP id n3so925510pgr.9 for ; Wed, 08 Feb 2023 22:30:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20210112.gappssmtp.com; s=20210112; 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=qlPh49wlbxVVcOm0Ok3pVswLtoV2NRPuPBXAw/YmxdU=; b=wp7Yab735sy01MLbrgfsOESNTTb0h03RSrJ/08EgpczVM5M4TOzymFCeAMkBPWNKNm /g1h/CZZe0fb3FfaFNqX+OAFyjrcrBdPVjnQq0Kx7qAHYBLyEBm78e3RoNJxISh7jQhJ MJJ/Yav2m4F8+LFZFtFrtG7K8gIiW5DwvLnQSrUBM6CwE7hd7dVoqIUWa7ZEfcmj3ju1 MG2GO6wEykuI4qOei9WjgWfNJCK2D3lr3rhUeawqFWlHLSGl1m5iMggZmHi2wr9aPqJ/ AeAgOPh1/r98lGKVpSrfuygrqNxG1PcOCEM+7dmG0HKtN7W1Ebfwl8PP6UZ4eSaHC6kK QdyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=qlPh49wlbxVVcOm0Ok3pVswLtoV2NRPuPBXAw/YmxdU=; b=R34bNpzY34RB881wQjfnI9fhXBReXhIb/9ZOgv9J9hBTCr3ICoCI8p2gQla9u7cv00 Enqeif+cahIaL8koRl3HzaDXT2nshBAqb9a3DRVNOsW/qWJjOHTsCWMuZsY5LJTO+KKj dQvmfBiuq1cK/vMguz7D/n/w49MmayBVe7sjGeTa7yc411Ofom+QN6l7QvE3z22lF/C9 b5BOM/qRksgkFNpeITh1yjVVj796TBR2Y+Ft4alfLKImNAMcUrMKFAJVrMFxo398bnF6 qw9Q+4Qj7Mul3KgMp+uqf3fondp+YzsJsXw6yDY3L2Tmxl5jqYb8Loddyx8Gk4BhaJax G+JQ== X-Gm-Message-State: AO0yUKVTeqpGIXqyzsdupqzklHAh57aNkdu64trA90vqMnC9u46VUigb jQg+VV1nRm3l9A1/WYtaKq9B7OrEd2Jz9X40 X-Google-Smtp-Source: AK7set+aIDc0/0LKIFdjo4kcedHR8xbTL6xdARubTtD7bXEb5o15/SNrwLDEuTLZt/kWuRc8gRkwVA== X-Received: by 2002:a62:1a4f:0:b0:593:b491:40b8 with SMTP id a76-20020a621a4f000000b00593b49140b8mr8361545pfa.4.1675924224570; Wed, 08 Feb 2023 22:30:24 -0800 (PST) Received: from debug.ba.rivosinc.com ([66.220.2.162]) by smtp.gmail.com with ESMTPSA id u15-20020aa7848f000000b00593c434b1b8sm543649pfn.48.2023.02.08.22.30.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 08 Feb 2023 22:30:24 -0800 (PST) From: Deepak Gupta To: qemu-devel@nongnu.org, Palmer Dabbelt , Alistair Francis , Bin Meng Cc: Deepak Gupta , Kip Walker , qemu-riscv@nongnu.org Subject: [PATCH v1 RFC Zisslpcfi 2/9] target/riscv: zisslpcfi CSR, bit positions and other definitions Date: Wed, 8 Feb 2023 22:29:40 -0800 Message-Id: <20230209062947.3585481-3-debug@rivosinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230209062947.3585481-1-debug@rivosinc.com> References: <20230209062947.3585481-1-debug@rivosinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::530; envelope-from=debug@rivosinc.com; helo=mail-pg1-x530.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 autolearn=unavailable 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+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org `zisslpcfi` extension adds two new CSRs. CSR_SSP and CSR_LPLR. - CSR_SSP: This CSR holds shadow stack pointer for current privilege mode CSR_SSP is accessible in all modes. Each mode must establish it's own CSR_SSP. - CSR_LPLR: This CSR holds label value set at the callsite by compiler. On call target label check instructions are emitted by compiler which check label value against value present in CSR_LPRL. Enabling of `zisslpcfi` is controlled via menvcfg (for S/HS/VS/U/VU) and henvcfg (for VS/VU) at bit position 60. Each mode has enable/disable bits for forward cfi. Backward cfi doesn't have separate enable/disable bits for S and M mode. User forward cfi and user backward cfi enable/disable bits are in mstatus/sstatus CSR. Supervisor forward cfi enable/disable bit are in menvcfg and henvcfg CSR. Machine mode forward cfi enable/disable bit is in mseccfg CSR. If forward cfi enabled, all indirect branches must land on a landing pad instruction (`lpcll`, introduced in later commits). CPU/hart tracks this internally using a landing pad tracker called `elp` short for `expecting landing pad`. An interrupt can occur between an indirect branch and target. If such an event occurs `elp` is saved away in mstatus/sstatus CSR Signed-off-by: Deepak Gupta Signed-off-by: Kip Walker --- target/riscv/cpu.h | 5 +++++ target/riscv/cpu_bits.h | 25 +++++++++++++++++++++++++ target/riscv/pmp.h | 3 ++- 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 9a923760b2..18db61a06a 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -181,6 +181,11 @@ struct CPUArchState { uint32_t features; + /* CFI Extension user mode registers and state */ + uint32_t lplr; + target_ulong ssp; + cfi_elp elp; + #ifdef CONFIG_USER_ONLY uint32_t elf_flags; #endif diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index 8b0d7e20ea..1663ba5775 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -39,6 +39,10 @@ /* Control and Status Registers */ +/* CFI CSRs */ +#define CSR_LPLR 0x006 +#define CSR_SSP 0x020 + /* User Trap Setup */ #define CSR_USTATUS 0x000 #define CSR_UIE 0x004 @@ -542,6 +546,10 @@ #define MSTATUS_TVM 0x00100000 /* since: priv-1.10 */ #define MSTATUS_TW 0x00200000 /* since: priv-1.10 */ #define MSTATUS_TSR 0x00400000 /* since: priv-1.10 */ +#define MSTATUS_UFCFIEN 0x00800000 /* Zisslpcfi-0.1 */ +#define MSTATUS_UBCFIEN 0x01000000 /* Zisslpcfi-0.1 */ +#define MSTATUS_SPELP 0x02000000 /* Zisslpcfi-0.1 */ +#define MSTATUS_MPELP 0x04000000 /* Zisslpcfi-0.1 */ #define MSTATUS_GVA 0x4000000000ULL #define MSTATUS_MPV 0x8000000000ULL @@ -572,12 +580,21 @@ typedef enum { #define SSTATUS_XS 0x00018000 #define SSTATUS_SUM 0x00040000 /* since: priv-1.10 */ #define SSTATUS_MXR 0x00080000 +#define SSTATUS_UFCFIEN MSTATUS_UFCFIEN /* Zisslpcfi-0.1 */ +#define SSTATUS_UBCFIEN MSTATUS_UBCFIEN /* Zisslpcfi-0.1 */ +#define SSTATUS_SPELP MSTATUS_SPELP /* Zisslpcfi-0.1 */ #define SSTATUS64_UXL 0x0000000300000000ULL #define SSTATUS32_SD 0x80000000 #define SSTATUS64_SD 0x8000000000000000ULL +#define CFISTATUS_M_MASK (MSTATUS_UFCFIEN | MSTATUS_UBCFIEN | \ + MSTATUS_MPELP | MSTATUS_SPELP) + +#define CFISTATUS_S_MASK (SSTATUS_UFCFIEN | SSTATUS_UBCFIEN | \ + SSTATUS_SPELP) + /* hstatus CSR bits */ #define HSTATUS_VSBE 0x00000020 #define HSTATUS_GVA 0x00000040 @@ -747,10 +764,14 @@ typedef enum RISCVException { #define MENVCFG_CBIE (3UL << 4) #define MENVCFG_CBCFE BIT(6) #define MENVCFG_CBZE BIT(7) +#define MENVCFG_SFCFIEN BIT(59) +#define MENVCFG_CFI BIT(60) #define MENVCFG_PBMTE (1ULL << 62) #define MENVCFG_STCE (1ULL << 63) /* For RV32 */ +#define MENVCFGH_SFCFIEN BIT(27) +#define MENVCFGH_CFI BIT(28) #define MENVCFGH_PBMTE BIT(30) #define MENVCFGH_STCE BIT(31) @@ -763,10 +784,14 @@ typedef enum RISCVException { #define HENVCFG_CBIE MENVCFG_CBIE #define HENVCFG_CBCFE MENVCFG_CBCFE #define HENVCFG_CBZE MENVCFG_CBZE +#define HENVCFG_SFCFIEN MENVCFG_SFCFIEN +#define HENVCFG_CFI MENVCFG_CFI #define HENVCFG_PBMTE MENVCFG_PBMTE #define HENVCFG_STCE MENVCFG_STCE /* For RV32 */ +#define HENVCFGH_SFCFIEN MENVCFGH_SFCFIEN +#define HENVCFGH_CFI MENVCFGH_CFI #define HENVCFGH_PBMTE MENVCFGH_PBMTE #define HENVCFGH_STCE MENVCFGH_STCE diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h index da32c61c85..f5bfc4955b 100644 --- a/target/riscv/pmp.h +++ b/target/riscv/pmp.h @@ -43,7 +43,8 @@ typedef enum { MSECCFG_MMWP = 1 << 1, MSECCFG_RLB = 1 << 2, MSECCFG_USEED = 1 << 8, - MSECCFG_SSEED = 1 << 9 + MSECCFG_SSEED = 1 << 9, + MSECCFG_MFCFIEN = 1 << 10 } mseccfg_field_t; typedef struct { From patchwork Thu Feb 9 06:29:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Deepak Gupta X-Patchwork-Id: 1739819 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=rivosinc-com.20210112.gappssmtp.com header.i=@rivosinc-com.20210112.gappssmtp.com header.a=rsa-sha256 header.s=20210112 header.b=rAR8VWF9; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4PC6W14Hw3z23jH for ; Thu, 9 Feb 2023 17:33:01 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pQ0SP-0007jb-Vq; Thu, 09 Feb 2023 01:30:58 -0500 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 1pQ0Ry-0007XJ-Iw for qemu-devel@nongnu.org; Thu, 09 Feb 2023 01:30:33 -0500 Received: from mail-pf1-x42d.google.com ([2607:f8b0:4864:20::42d]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pQ0Rv-0000lz-P9 for qemu-devel@nongnu.org; Thu, 09 Feb 2023 01:30:29 -0500 Received: by mail-pf1-x42d.google.com with SMTP id ay1so677349pfb.7 for ; Wed, 08 Feb 2023 22:30:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20210112.gappssmtp.com; s=20210112; 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=OjYZ/J+fuGuBPvfefUWdX1uo98embzdFhANJFdid3iE=; b=rAR8VWF9zlhYCpSTouQKKoTw01SlrbXB0M9SwvjXoxxidhTccal3yizJHUAJZ+xP7b WMsS+0beUbd+46D3KwrBDjJwa+c/fUgJkDQEwryNS1k35rau8xASVilNiDmeS+OKylym +XrpFiUxvfcajaEO/XnGgdv0ACknAn7S++s72aAD9iUXdWfCd4g/zvGdtkYyq3MrtDQ+ GLXQ+EgXdVO0so8wsb0e7HdtlqTcmUUPSUnueAMlomrxVy84nDoIOZvuWJ23IS8WbHKE KTxK+lsHgdQ7Wadsc8lNsudJpe36bvNgz4xq0lkU5BIr+oOE+bvqkJ10Lf6eqD5iAHBl R/Ww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=OjYZ/J+fuGuBPvfefUWdX1uo98embzdFhANJFdid3iE=; b=eL4BAdXilMRuWOIYcV145JfCtrFtufU6IzybLeCAmotho14eu+/LcULo62krrahUsv aZdDZKPJ+rtuRqr+6v7BWkCbj2QPwMx0L+NiqBi7YXRtCj94I7nXoLeTl+x59LMBEj5B UZdPVp0nqjI/s0kf4AcvuluGpN+KYDqI+jGl2fgqptDXY+u2k/ShdlS8bdFOZ3pJHos3 ZkTrNe/4tisbb8P8E8Gita4WFkg9oCFMcqhesqPD/EYK2i3PxOxdCyAa45t1mQDSvVGs qOhkKzaV+2qZLiWzNTqNycvb+KQv/XHYmo2+OHRlSkWMW6qT/0F4qRMcWdzZQik5RT2B EXFA== X-Gm-Message-State: AO0yUKVtafew/xMkFf+74jSJMiPtBzIRpBjjDB792W+5JXfTRiYmikkH v1eZTTdjyP4CGtNbIxzP7/5RptLxcBJBOqPh X-Google-Smtp-Source: AK7set9mCoTyNmsch3hUqxj7KNogzcy+Nv/CUfbPbZeDbhaQyMWcIQd3C/uE5MLCRozN5149jta9Hw== X-Received: by 2002:aa7:9eca:0:b0:5a8:4b4a:8480 with SMTP id r10-20020aa79eca000000b005a84b4a8480mr3225343pfq.23.1675924225831; Wed, 08 Feb 2023 22:30:25 -0800 (PST) Received: from debug.ba.rivosinc.com ([66.220.2.162]) by smtp.gmail.com with ESMTPSA id u15-20020aa7848f000000b00593c434b1b8sm543649pfn.48.2023.02.08.22.30.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 08 Feb 2023 22:30:25 -0800 (PST) From: Deepak Gupta To: qemu-devel@nongnu.org, Palmer Dabbelt , Alistair Francis , Bin Meng Cc: Deepak Gupta , Kip Walker , qemu-riscv@nongnu.org Subject: [PATCH v1 RFC Zisslpcfi 3/9] target/riscv: implements CSRs and new bits in existing CSRs in zisslpcfi Date: Wed, 8 Feb 2023 22:29:41 -0800 Message-Id: <20230209062947.3585481-4-debug@rivosinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230209062947.3585481-1-debug@rivosinc.com> References: <20230209062947.3585481-1-debug@rivosinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::42d; envelope-from=debug@rivosinc.com; helo=mail-pf1-x42d.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 autolearn=unavailable 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+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org CSR_SSP and CSR_LPLR are new CSR additions to cpu/hart. This patch allows access to these CSRs. A predicate routine handles access to these CSR as per specification. This patch also implments new bit definitions in menvcfg/henvcfg/mstatus/ sstatus CSRs to master enabled cfi and enable forward cfi in S and M mode. mstatus CSR holds forward and backward cfi enabling for U mode. There is no enabling bit for backward cfi in S and M mode. It is always enabled if extension is implemented by CPU. Signed-off-by: Deepak Gupta Signed-off-by: Kip Walker --- target/riscv/csr.c | 137 ++++++++++++++++++++++++++++++++++++++++++++- target/riscv/pmp.c | 9 +++ 2 files changed, 145 insertions(+), 1 deletion(-) diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 0db2c233e5..24e208ebed 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -163,6 +163,50 @@ static RISCVException ctr32(CPURISCVState *env, int csrno) return ctr(env, csrno); } +static RISCVException cfi(CPURISCVState *env, int csrno) +{ + /* no cfi extension */ + if (!env_archcpu(env)->cfg.ext_cfi) { + return RISCV_EXCP_ILLEGAL_INST; + } + /* + * CONFIG_USER_MODE always allow access for now. Better for user mode only + * functionality + */ +#if !defined(CONFIG_USER_ONLY) + /* current priv not M */ + if (env->priv != PRV_M) { + /* menvcfg says no CFI */ + if (!get_field(env->menvcfg, MENVCFG_CFI)) { + return RISCV_EXCP_ILLEGAL_INST; + } + + /* V = 1 and henvcfg says no CFI. raise virtual instr fault */ + if (riscv_cpu_virt_enabled(env) && + !get_field(env->henvcfg, HENVCFG_CFI)) { + return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; + } + + /* + * LPLR and SSP are not accessible to U mode if disabled via status + * CSR + */ + if (env->priv == PRV_U) { + if (csrno == CSR_LPLR && + !get_field(env->mstatus, MSTATUS_UFCFIEN)) { + return RISCV_EXCP_ILLEGAL_INST; + } + if (csrno == CSR_SSP && + !get_field(env->mstatus, MSTATUS_UBCFIEN)) { + return RISCV_EXCP_ILLEGAL_INST; + } + } + } +#endif + + return RISCV_EXCP_NONE; +} + #if !defined(CONFIG_USER_ONLY) static RISCVException mctr(CPURISCVState *env, int csrno) { @@ -485,6 +529,32 @@ static RISCVException seed(CPURISCVState *env, int csrno) #endif } +/* Zisslpcfi CSR_LPLR read/write */ +static int read_lplr(CPURISCVState *env, int csrno, target_ulong *val) +{ + *val = env->lplr; + return RISCV_EXCP_NONE; +} + +static int write_lplr(CPURISCVState *env, int csrno, target_ulong val) +{ + env->lplr = val & (LPLR_UL | LPLR_ML | LPLR_LL); + return RISCV_EXCP_NONE; +} + +/* Zisslpcfi CSR_SSP read/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) @@ -1227,7 +1297,7 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno, /* flush tlb on mstatus fields that affect VM */ if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP | MSTATUS_MPV | - MSTATUS_MPRV | MSTATUS_SUM)) { + MSTATUS_MPRV | MSTATUS_SUM | MSTATUS_UFCFIEN | MSTATUS_UBCFIEN)) { tlb_flush(env_cpu(env)); } mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE | @@ -1250,6 +1320,11 @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno, } } + /* If cfi extension is available, then apply cfi status mask */ + if (env_archcpu(env)->cfg.ext_cfi) { + mask |= CFISTATUS_M_MASK; + } + mstatus = (mstatus & ~mask) | (val & mask); if (xl > MXL_RV32) { @@ -1880,9 +1955,17 @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno, target_ulong val) { uint64_t mask = MENVCFG_FIOM | MENVCFG_CBIE | MENVCFG_CBCFE | MENVCFG_CBZE; + uint64_t cfi_mask = MENVCFG_CFI | MENVCFG_SFCFIEN; if (riscv_cpu_mxl(env) == MXL_RV64) { mask |= MENVCFG_PBMTE | MENVCFG_STCE; + if (env_archcpu(env)->cfg.ext_cfi) { + mask |= cfi_mask; + /* If any cfi enabling bit changes in menvcfg, flush tlb */ + if ((val ^ env->menvcfg) & cfi_mask) { + tlb_flush(env_cpu(env)); + } + } } env->menvcfg = (env->menvcfg & ~mask) | (val & mask); @@ -1900,8 +1983,17 @@ static RISCVException write_menvcfgh(CPURISCVState *env, int csrno, target_ulong val) { uint64_t mask = MENVCFG_PBMTE | MENVCFG_STCE; + uint64_t cfi_mask = MENVCFG_CFI | MENVCFG_SFCFIEN; uint64_t valh = (uint64_t)val << 32; + if (env_archcpu(env)->cfg.ext_cfi) { + mask |= cfi_mask; + /* If any cfi enabling bit changes in menvcfg, flush tlb */ + if ((val ^ env->menvcfg) & cfi_mask) { + tlb_flush(env_cpu(env)); + } + } + env->menvcfg = (env->menvcfg & ~mask) | (valh & mask); return RISCV_EXCP_NONE; @@ -1954,6 +2046,7 @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno, target_ulong val) { uint64_t mask = HENVCFG_FIOM | HENVCFG_CBIE | HENVCFG_CBCFE | HENVCFG_CBZE; + uint64_t cfi_mask = HENVCFG_CFI | HENVCFG_SFCFIEN; RISCVException ret; ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG); @@ -1963,6 +2056,18 @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno, if (riscv_cpu_mxl(env) == MXL_RV64) { mask |= HENVCFG_PBMTE | HENVCFG_STCE; + /* + * If cfi available and menvcfg.CFI = 1, then apply cfi mask for + * henvcfg + */ + if (env_archcpu(env)->cfg.ext_cfi && + get_field(env->menvcfg, MENVCFG_CFI)) { + mask |= cfi_mask; + /* If any cfi enabling bit changes in henvcfg, flush tlb */ + if ((val ^ env->henvcfg) & cfi_mask) { + tlb_flush(env_cpu(env)); + } + } } env->henvcfg = (env->henvcfg & ~mask) | (val & mask); @@ -1988,9 +2093,19 @@ static RISCVException write_henvcfgh(CPURISCVState *env, int csrno, target_ulong val) { uint64_t mask = HENVCFG_PBMTE | HENVCFG_STCE; + uint64_t cfi_mask = HENVCFG_CFI | HENVCFG_SFCFIEN; uint64_t valh = (uint64_t)val << 32; RISCVException ret; + if (env_archcpu(env)->cfg.ext_cfi && + get_field(env->menvcfg, MENVCFG_CFI)) { + mask |= cfi_mask; + /* If any cfi enabling bit changes in henvcfg, flush tlb */ + if ((val ^ env->henvcfg) & cfi_mask) { + tlb_flush(env_cpu(env)); + } + } + ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG); if (ret != RISCV_EXCP_NONE) { return ret; @@ -2270,6 +2385,11 @@ static RISCVException read_sstatus_i128(CPURISCVState *env, int csrno, mask |= SSTATUS64_UXL; } + if ((env_archcpu(env)->cfg.ext_cfi) && + get_field(env->menvcfg, MENVCFG_CFI)) { + mask |= CFISTATUS_S_MASK; + } + *val = int128_make128(sstatus, add_status_sd(MXL_RV128, sstatus)); return RISCV_EXCP_NONE; } @@ -2281,6 +2401,11 @@ static RISCVException read_sstatus(CPURISCVState *env, int csrno, if (env->xl != MXL_RV32 || env->debugger) { mask |= SSTATUS64_UXL; } + + if ((env_archcpu(env)->cfg.ext_cfi) && + get_field(env->menvcfg, MENVCFG_CFI)) { + mask |= CFISTATUS_S_MASK; + } /* TODO: Use SXL not MXL. */ *val = add_status_sd(riscv_cpu_mxl(env), env->mstatus & mask); return RISCV_EXCP_NONE; @@ -2296,6 +2421,12 @@ static RISCVException write_sstatus(CPURISCVState *env, int csrno, mask |= SSTATUS64_UXL; } } + + /* If cfi available and menvcfg.CFI = 1, apply CFI mask for sstatus */ + if ((env_archcpu(env)->cfg.ext_cfi) && + get_field(env->menvcfg, MENVCFG_CFI)) { + mask |= CFISTATUS_S_MASK; + } target_ulong newval = (env->mstatus & ~mask) | (val & mask); return write_mstatus(env, CSR_MSTATUS, newval); } @@ -4001,6 +4132,10 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { /* Crypto Extension */ [CSR_SEED] = { "seed", seed, NULL, NULL, rmw_seed }, + /* User mode CFI CSR */ + [CSR_LPLR] = { "lplr", cfi, read_lplr, write_lplr }, + [CSR_SSP] = { "ssp", cfi, read_ssp, write_ssp }, + #if !defined(CONFIG_USER_ONLY) /* Machine Timers and Counters */ [CSR_MCYCLE] = { "mcycle", any, read_hpmcounter, diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c index d1126a6066..89745d46cd 100644 --- a/target/riscv/pmp.c +++ b/target/riscv/pmp.c @@ -579,6 +579,15 @@ void mseccfg_csr_write(CPURISCVState *env, target_ulong val) /* Sticky bits */ val |= (env->mseccfg & (MSECCFG_MMWP | MSECCFG_MML)); + /* M-mode forward cfi to be enabled if cfi extension is implemented */ + if (env_archcpu(env)->cfg.ext_cfi) { + val |= (val & MSECCFG_MFCFIEN); + /* If forward cfi in mseccfg is being toggled, flush tlb */ + if ((env->mseccfg ^ val) & MSECCFG_MFCFIEN) { + tlb_flush(env_cpu(env)); + } + } + env->mseccfg = val; } From patchwork Thu Feb 9 06:29:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Deepak Gupta X-Patchwork-Id: 1739814 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=rivosinc-com.20210112.gappssmtp.com header.i=@rivosinc-com.20210112.gappssmtp.com header.a=rsa-sha256 header.s=20210112 header.b=FpWYYk/+; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4PC6TT49jPz23yF for ; Thu, 9 Feb 2023 17:31:41 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pQ0SO-0007hr-TI; Thu, 09 Feb 2023 01:30:57 -0500 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 1pQ0S1-0007Xh-Jy for qemu-devel@nongnu.org; Thu, 09 Feb 2023 01:30:33 -0500 Received: from mail-pf1-x435.google.com ([2607:f8b0:4864:20::435]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pQ0Ry-0000mP-Ba for qemu-devel@nongnu.org; Thu, 09 Feb 2023 01:30:33 -0500 Received: by mail-pf1-x435.google.com with SMTP id r17so670480pff.9 for ; Wed, 08 Feb 2023 22:30:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20210112.gappssmtp.com; s=20210112; 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=slc2qEJKHDUPCqJbT+o4fG/GNXtlIN4HHpf/pKqJaTw=; b=FpWYYk/+rObx8lj8TiUpzTGreHoqDxf0meG0ATcWaJEIBQyKv4sfm/s8Yhiotq4tZw V/XWiUCLWMfyv++0IrQxElMBNBWWhGlPWkS94HuLnoTE1YYFxx6EZfUAnWIX2M0/yBwm L0DGybx/GMc8JKTIey1tmlqXisSRqHFLw6jHSJO3pTDIy0QDd8WSVwxw8TXQaukURNh7 0nmYyfW8LAUgbrqfHeLrg/Rsi+WglTE3kUFMFAsLJzKxaMHCpcEEsyIMZGQwv+Y4Zb80 da9cnRWbIWYsYhGCOSfHbZgBgUl7TQ+LIuo/lhy8tc771Sv3gRRZhJjRfzyCmh22UIfL EuMw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=slc2qEJKHDUPCqJbT+o4fG/GNXtlIN4HHpf/pKqJaTw=; b=i1HRNw3Fu5usWVLpONFVl0nHu6w3ME/H8BQZct4169NuJO+0g5PK+dYaUVlWZqyUOF E7f8PCb2BRctLsaeyaTg372dpxI0CG7dBuPBDGTDpBpFU/VowWhmvDVfiaqspllryJkO cl29xS9yzne6B7RvTFKVGXJLKP/gdoNpoiSEZO1RnVw0McHwbayGmkLN/1CreKrL0Gvn MlAuuXzc0UhdJphiDevN5fwCxc6QPYN9fV309T6DHzweGtQqOg4SmiIQcwyPTAiqx4pL PuRS2oSiv6f2YN7tWgZY+THs/hxYX42r65xIK2kZpxygzpZGHXtv7vxw/5GPVOidqAiJ WAeg== X-Gm-Message-State: AO0yUKWTR+urfr7frZgor9UpBb/rKIUqxeQDjgX4BSGE+JBW7oNwAjsG boI/YB6TyRpFhAVWX4ol69Lefqfd1F2mFOF1 X-Google-Smtp-Source: AK7set/A7D+BkYZDhyi+L9nqEefqaNyFJWmscGPQA23xnsPgoqPtMaybiQ2AyGA3/EF5GJdiM1hasw== X-Received: by 2002:a62:520a:0:b0:5a8:44b1:7396 with SMTP id g10-20020a62520a000000b005a844b17396mr4414023pfb.15.1675924227118; Wed, 08 Feb 2023 22:30:27 -0800 (PST) Received: from debug.ba.rivosinc.com ([66.220.2.162]) by smtp.gmail.com with ESMTPSA id u15-20020aa7848f000000b00593c434b1b8sm543649pfn.48.2023.02.08.22.30.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 08 Feb 2023 22:30:26 -0800 (PST) From: Deepak Gupta To: qemu-devel@nongnu.org, Palmer Dabbelt , Alistair Francis , Bin Meng Cc: Deepak Gupta , Kip Walker , qemu-riscv@nongnu.org Subject: [PATCH v1 RFC Zisslpcfi 4/9] target/riscv: helper functions for forward and backward cfi Date: Wed, 8 Feb 2023 22:29:42 -0800 Message-Id: <20230209062947.3585481-5-debug@rivosinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230209062947.3585481-1-debug@rivosinc.com> References: <20230209062947.3585481-1-debug@rivosinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::435; envelope-from=debug@rivosinc.com; helo=mail-pf1-x435.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 autolearn=unavailable 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+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Implementation for forward cfi and backward cfi needs helper function to determine if currently fcfi and bcfi are enabled. Enable depends on privilege mode and settings in sstatus/menvcfg/henvcfg/mseccfg CSRs. Signed-off-by: Deepak Gupta Signed-off-by: Kip Walker --- target/riscv/cpu.h | 2 ++ target/riscv/cpu_helper.c | 51 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 18db61a06a..d14ea4f91d 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -568,6 +568,8 @@ bool riscv_cpu_virt_enabled(CPURISCVState *env); void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable); bool riscv_cpu_two_stage_lookup(int mmu_idx); int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch); +bool cpu_get_fcfien(CPURISCVState *env); +bool cpu_get_bcfien(CPURISCVState *env); hwaddr riscv_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); G_NORETURN void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr, MMUAccessType access_type, int mmu_idx, diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 9a28816521..a397023840 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -30,6 +30,7 @@ #include "sysemu/cpu-timers.h" #include "cpu_bits.h" #include "debug.h" +#include "pmp.h" int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch) { @@ -40,6 +41,56 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch) #endif } +bool cpu_get_fcfien(CPURISCVState *env) +{ +#ifdef CONFIG_USER_ONLY + return false; +#else + /* no cfi extension, return false */ + if (!env_archcpu(env)->cfg.ext_cfi) { + return false; + } + + switch (env->priv) { + case PRV_U: + return (env->mstatus & MSTATUS_UFCFIEN) ? true : false; + case PRV_S: + return (env->menvcfg & MENVCFG_SFCFIEN) ? true : false; + case PRV_M: + return (env->mseccfg & MSECCFG_MFCFIEN) ? true : false; + default: + g_assert_not_reached(); + } +#endif +} + +bool cpu_get_bcfien(CPURISCVState *env) +{ +#ifdef CONFIG_USER_ONLY + return false; +#else + /* no cfi extension, return false */ + if (!env_archcpu(env)->cfg.ext_cfi) { + return false; + } + + switch (env->priv) { + case PRV_U: + return (env->mstatus & MSTATUS_UBCFIEN) ? true : false; + + /* + * no gating for back cfi in M/S mode. back cfi is always on for + * M/S mode + */ + case PRV_S: + case PRV_M: + return true; + default: + g_assert_not_reached(); + } +#endif +} + void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc, target_ulong *cs_base, uint32_t *pflags) { From patchwork Thu Feb 9 06:29:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Deepak Gupta X-Patchwork-Id: 1739812 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=rivosinc-com.20210112.gappssmtp.com header.i=@rivosinc-com.20210112.gappssmtp.com header.a=rsa-sha256 header.s=20210112 header.b=BJp4gQFJ; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4PC6TQ0cxdz23jH for ; Thu, 9 Feb 2023 17:31:38 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pQ0SQ-0007jj-7o; Thu, 09 Feb 2023 01:30:58 -0500 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 1pQ0S1-0007Xg-Hi for qemu-devel@nongnu.org; Thu, 09 Feb 2023 01:30:33 -0500 Received: from mail-pg1-x531.google.com ([2607:f8b0:4864:20::531]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pQ0Ry-0000mj-Bi for qemu-devel@nongnu.org; Thu, 09 Feb 2023 01:30:33 -0500 Received: by mail-pg1-x531.google.com with SMTP id 78so934377pgb.8 for ; Wed, 08 Feb 2023 22:30:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20210112.gappssmtp.com; s=20210112; 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=MgwkEef7vxsb/V1HXgcHLlMSEMyA02TSLlxvE3Cow40=; b=BJp4gQFJur4hucyaYSCMV0vWmBA3IXMp/46pWJrHezGegEO6bIjfmI0loHUB1yMQ37 P8Rsm8cIEWrlpYCniqF3ubP/WnTnSw9uvGUgjehPu5M2nLaDlFJL57ezNhw6uBdoFupt u7q3NXT7gtkZ9LgedS457rtDyzABbjW+lgAoszhQHYXzNBQ6UrEIhYZevcAUG1Sftq1v ujgXNqUnWhCaP2FQKCXqJnx9VpscJodcW3cwDV1PxIXocvswjrmeIm4h/z9WAZZC2EFA 5sWG4sXxhh7QXLVHaon0VO16f9iW0LJ6SyyaqukE68Iyf9SsKIGbEIyXkdn3GmWB29D1 S3TA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=MgwkEef7vxsb/V1HXgcHLlMSEMyA02TSLlxvE3Cow40=; b=EXPwAJpEca5pKR5ylqyNUZk5G4JYZ+VUACPPFnNuFeyC+h/AOF/is4Ew/T9tleA0r8 nS6pEIY6qkko9ZjYKhymA7cvp7p8z7itIcjiSECRQMBLcrRYHcReleXw/PId4Rlcbo4+ BG+ftkkG0pU8GZTQ7fPMnQQ+ZesMiW4bb9as+vMWSZYNHE0FOWj8jH3vEz7mzo3pgFys 3ya1+tUyPlvChwaMr97a+WeVbwpC1WdpkOxKKm2cJIs1vrE31vlF0ZyZBL06Cdr/ZUDI 3Lcg8JaUvUn48x0anZS7tq5cRaAToQ4emBYv+o2pWxWQTgnqU+81u2EM7fed134I4cJI 9hAg== X-Gm-Message-State: AO0yUKXqqfFrw7LUQSwGV+Ge3YihACQKvffHSv7VPUSYVB+wddz7Ne9V uDxGdmkxPFoSYY2ho1Ppqo4cMlM1/+H8BFzM X-Google-Smtp-Source: AK7set9P/26eCJIVugsXypbPsucHIQ7Hqq6zaq01bzPHVb5fOvd0SegnQS6U2Vb0FiJEChsi1siAjA== X-Received: by 2002:aa7:9509:0:b0:594:26a7:cbd2 with SMTP id b9-20020aa79509000000b0059426a7cbd2mr1002962pfp.8.1675924228350; Wed, 08 Feb 2023 22:30:28 -0800 (PST) Received: from debug.ba.rivosinc.com ([66.220.2.162]) by smtp.gmail.com with ESMTPSA id u15-20020aa7848f000000b00593c434b1b8sm543649pfn.48.2023.02.08.22.30.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 08 Feb 2023 22:30:27 -0800 (PST) From: Deepak Gupta To: qemu-devel@nongnu.org, Palmer Dabbelt , Alistair Francis , Bin Meng Cc: Deepak Gupta , Kip Walker , qemu-riscv@nongnu.org Subject: [PATCH v1 RFC Zisslpcfi 5/9] target/riscv: state save and restore of zisslppcfi state Date: Wed, 8 Feb 2023 22:29:43 -0800 Message-Id: <20230209062947.3585481-6-debug@rivosinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230209062947.3585481-1-debug@rivosinc.com> References: <20230209062947.3585481-1-debug@rivosinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::531; envelope-from=debug@rivosinc.com; helo=mail-pg1-x531.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 autolearn=unavailable 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+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org zisslpcfi's forward cfi if enabled on a hart, enables tracking of indirect branches. CPU/hart internally keeps a state `elp` short for expecting landing pad instruction. This state goes into LP_EXPECTED on an indirect branch. But an interrupt/exception can occur before target instruction is executed. In such a case this state must be preserved so that it can be restored later. zisslpcfi saves elp state in `sstatus` CSR. This patch saves elp state in sstatus CSR on trap delivery while restores from sstatus CSR on trap return. Additionally state in sstatus CSR must have save and restore zisslpcfi state on exiting from hypervisor and entering into hypervisor. Signed-off-by: Deepak Gupta Signed-off-by: Kip Walker --- target/riscv/cpu_bits.h | 5 +++++ target/riscv/cpu_helper.c | 26 ++++++++++++++++++++++++++ target/riscv/op_helper.c | 12 ++++++++++++ 3 files changed, 43 insertions(+) diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index 1663ba5775..37100ec8f6 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -594,6 +594,11 @@ typedef enum { #define CFISTATUS_S_MASK (SSTATUS_UFCFIEN | SSTATUS_UBCFIEN | \ SSTATUS_SPELP) +/* enum for branch tracking state in cpu/hart */ +typedef enum { + NO_LP_EXPECTED = 0, + LP_EXPECTED = 1, +} cfi_elp; /* hstatus CSR bits */ #define HSTATUS_VSBE 0x00000020 diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index a397023840..fc188683c9 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -534,6 +534,16 @@ void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env) if (riscv_has_ext(env, RVF)) { mstatus_mask |= MSTATUS_FS; } + + /* + * If cfi extension available, menvcfg.CFI = 1 and henvcfg.CFI = 1, + * then apply CFI mask on mstatus + */ + if (env_archcpu(env)->cfg.ext_cfi && + get_field(env->menvcfg, MENVCFG_CFI) && + get_field(env->henvcfg, HENVCFG_CFI)) { + mstatus_mask |= CFISTATUS_S_MASK; + } bool current_virt = riscv_cpu_virt_enabled(env); g_assert(riscv_has_ext(env, RVH)); @@ -1723,6 +1733,10 @@ void riscv_cpu_do_interrupt(CPUState *cs) if (env->priv <= PRV_S && cause < TARGET_LONG_BITS && ((deleg >> cause) & 1)) { /* handle the trap in S-mode */ + /* save elp status */ + if (cpu_get_fcfien(env)) { + env->mstatus = set_field(env->mstatus, MSTATUS_SPELP, env->elp); + } if (riscv_has_ext(env, RVH)) { uint64_t hdeleg = async ? env->hideleg : env->hedeleg; @@ -1772,6 +1786,10 @@ void riscv_cpu_do_interrupt(CPUState *cs) riscv_cpu_set_mode(env, PRV_S); } else { /* handle the trap in M-mode */ + /* save elp status */ + if (cpu_get_fcfien(env)) { + env->mstatus = set_field(env->mstatus, MSTATUS_MPELP, env->elp); + } if (riscv_has_ext(env, RVH)) { if (riscv_cpu_virt_enabled(env)) { riscv_cpu_swap_hypervisor_regs(env); @@ -1803,6 +1821,14 @@ void riscv_cpu_do_interrupt(CPUState *cs) riscv_cpu_set_mode(env, PRV_M); } + /* + * Interrupt/exception/trap delivery is asynchronous event and as per + * Zisslpcfi spec CPU should clear up the ELP state. If cfi extension is + * available, clear ELP state. + */ + if (cpu->cfg.ext_cfi) { + env->elp = NO_LP_EXPECTED; + } /* NOTE: it is not necessary to yield load reservations here. It is only * necessary for an SC from "another hart" to cause a load reservation * to be yielded. Refer to the memory consistency model section of the diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c index 878bcb03b8..d15893aa82 100644 --- a/target/riscv/op_helper.c +++ b/target/riscv/op_helper.c @@ -176,6 +176,12 @@ target_ulong helper_sret(CPURISCVState *env) riscv_cpu_set_virt_enabled(env, prev_virt); } + /* If forward cfi enabled for target, restore elp status */ + if (cpu_get_fcfien(env)) { + env->elp = get_field(env->mstatus, MSTATUS_SPELP); + env->mstatus = set_field(env->mstatus, MSTATUS_SPELP, 0); + } + riscv_cpu_set_mode(env, prev_priv); return retpc; @@ -220,6 +226,12 @@ target_ulong helper_mret(CPURISCVState *env) riscv_cpu_set_virt_enabled(env, prev_virt); } + /* If forward cfi enabled for target, restore elp status */ + if (cpu_get_fcfien(env)) { + env->elp = get_field(env->mstatus, MSTATUS_MPELP); + env->mstatus = set_field(env->mstatus, MSTATUS_MPELP, 0); + } + return retpc; } From patchwork Thu Feb 9 06:29:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Deepak Gupta X-Patchwork-Id: 1739817 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=rivosinc-com.20210112.gappssmtp.com header.i=@rivosinc-com.20210112.gappssmtp.com header.a=rsa-sha256 header.s=20210112 header.b=5IG3vAmv; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4PC6Ty0573z23jH for ; Thu, 9 Feb 2023 17:32:06 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pQ0SU-0007qM-Mh; Thu, 09 Feb 2023 01:31:02 -0500 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 1pQ0S2-0007Yi-Hg for qemu-devel@nongnu.org; Thu, 09 Feb 2023 01:30:39 -0500 Received: from mail-pg1-x52d.google.com ([2607:f8b0:4864:20::52d]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pQ0Rz-0000n2-MV for qemu-devel@nongnu.org; Thu, 09 Feb 2023 01:30:34 -0500 Received: by mail-pg1-x52d.google.com with SMTP id 7so957747pga.1 for ; Wed, 08 Feb 2023 22:30:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20210112.gappssmtp.com; s=20210112; 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=jRqJiEOrxr+Lg5i/nVzezfWn+WGoCCcHshuxculEll8=; b=5IG3vAmvGgDwZGq7tnJZUkEBMgvW9CoqYKt7nNLRl7akcceSNKNMbO8fijFeRU5dVf jMDfCEFfnT6VU1ZxjZ3rsp9PlfccUqCFWrDPYi3kuQlHYfXWvz+9DsVAz/q3CS0b/9UF hf8W9MX+qEpMcC+vqvcsMtKcYpCLl9GfXvJPlEKtG15qQhV5nvKpJha02Qdh58QkQCjK 6ogDUoUJein3G/K+06+21NVMDWob3QPm+XUAJZxoSqfIn260togiKLN9JGWPay6XYCTe R2CZu6fHB2lgQSU0fkiAZygAR1Suwp/eND9M7sYp3dppRrDRQosyczI8D0HNAaW1g4DS THzQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=jRqJiEOrxr+Lg5i/nVzezfWn+WGoCCcHshuxculEll8=; b=bBB0+mJIL/1PsPMD0Xup39cfC02kTdyhLwSBL1Fks/Cyhbz8fFnJ6oV8rbCF/t01ay NeEOQFNECR2PovVaNiuX2H9TxJtXfMhh6y3wxitHPHM7TSqTs+7RsiCIi0zZX5xiLxb5 0FWlg3qCj2aBlECwa1etRFYSqbzZLj3UBOLK7ZbvyeEnN000ZqzFHI2nfNs9fJF2MhoR zxp7lttUIMjlP4Q7kacJ9fBzwDqt637LGgU91EcHNehIKOxYoSKQXkihLrojnHH4ctOe VkAN/Pz+s7JhR63rXnHxoOkxrezlC28sozsxg6C7OHTDFl6X0wVRcShBnfc64O0IzBnq S5Zg== X-Gm-Message-State: AO0yUKXl5HYbQrKuuSsEEtB/QsdMlR+xoYuxXE42zvhyyGB7HJujh1st 2BJJFDAUMl1RBljDcvf/b1c/AeYPV+3lGOnh X-Google-Smtp-Source: AK7set8ckSPtC1lVgoDHoNm3ES3BFmQnr+QN69AJNFLIWYMu/Bwy8BZZ1I2Y2vSQn0QgwvRiondujQ== X-Received: by 2002:a62:1503:0:b0:5a8:4c7e:bb01 with SMTP id 3-20020a621503000000b005a84c7ebb01mr2775706pfv.6.1675924229745; Wed, 08 Feb 2023 22:30:29 -0800 (PST) Received: from debug.ba.rivosinc.com ([66.220.2.162]) by smtp.gmail.com with ESMTPSA id u15-20020aa7848f000000b00593c434b1b8sm543649pfn.48.2023.02.08.22.30.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 08 Feb 2023 22:30:29 -0800 (PST) From: Deepak Gupta To: qemu-devel@nongnu.org, Palmer Dabbelt , Alistair Francis , Bin Meng Cc: Deepak Gupta , Kip Walker , qemu-riscv@nongnu.org Subject: [PATCH v1 RFC Zisslpcfi 6/9] target/riscv: MMU changes for back cfi's shadow stack Date: Wed, 8 Feb 2023 22:29:44 -0800 Message-Id: <20230209062947.3585481-7-debug@rivosinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230209062947.3585481-1-debug@rivosinc.com> References: <20230209062947.3585481-1-debug@rivosinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::52d; envelope-from=debug@rivosinc.com; helo=mail-pg1-x52d.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 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+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org zisslpcfi protects returns(back cfi) using shadow stack. If compiled with enabled compiler, function prologs will have `sspush ra` instruction to push return address on shadow stack and function epilogs will have `sspop t0; sschckra` instruction sequences. `sspop t0` will pop the value from top of the shadow stack in t0. `sschckra` will compare `t0` and `x1` and if they don't match then hart will raise an illegal instruction exception. Shadow stack is read-only memory except stores can be performed via `sspush` and `ssamoswap` instructions. This requires new PTE encoding for shadow stack. zisslpcfi uses R=0, W=1, X=0 (an existing reserved encoding ) to encode a shadow stack. If backward cfi is not enabled for current mode, shadow stack PTE encodings remain reserved. Regular stores to shadow stack raise AMO/store access fault. Shadow stack loads/stores on regular memory raise load access/store access fault. This patch creates a new MMU TLB index for shadow stack and flushes TLB for shadow stack on privileges changes. This patch doesn't implement `Smepmp` related enforcement on shadow stack pmp entry. Reason being qemu doesn't have `Smepmp` implementation yet. `Smepmp` enforcement should come whenever it is implemented. Signed-off-by: Deepak Gupta Signed-off-by: Kip Walker --- target/riscv/cpu-param.h | 1 + target/riscv/cpu.c | 2 + target/riscv/cpu.h | 3 ++ target/riscv/cpu_helper.c | 107 +++++++++++++++++++++++++++++++------- 4 files changed, 94 insertions(+), 19 deletions(-) diff --git a/target/riscv/cpu-param.h b/target/riscv/cpu-param.h index ebaf26d26d..a1e379beb7 100644 --- a/target/riscv/cpu-param.h +++ b/target/riscv/cpu-param.h @@ -25,6 +25,7 @@ * - M mode 0b011 * - U mode HLV/HLVX/HSV 0b100 * - S mode HLV/HLVX/HSV 0b101 + * - BCFI shadow stack 0b110 * - M mode HLV/HLVX/HSV 0b111 */ #define NB_MMU_MODES 8 diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 6b4e90eb91..14cfb93288 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -584,6 +584,8 @@ static void riscv_cpu_reset_hold(Object *obj) } /* mmte is supposed to have pm.current hardwired to 1 */ env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT); + /* Initialize ss_priv to current priv. */ + env->ss_priv = env->priv; #endif env->xl = riscv_cpu_mxl(env); riscv_cpu_update_mask(env); diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index d14ea4f91d..8803ea6426 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -379,6 +379,7 @@ struct CPUArchState { uint64_t sstateen[SMSTATEEN_MAX_COUNT]; target_ulong senvcfg; uint64_t henvcfg; + target_ulong ss_priv; #endif target_ulong cur_pmmask; target_ulong cur_pmbase; @@ -617,6 +618,8 @@ void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong); #define TB_FLAGS_PRIV_HYP_ACCESS_MASK (1 << 2) #define TB_FLAGS_MSTATUS_FS MSTATUS_FS #define TB_FLAGS_MSTATUS_VS MSTATUS_VS +/* TLB MMU index for shadow stack accesses */ +#define MMU_IDX_SS_ACCESS 6 #include "exec/cpu-all.h" diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index fc188683c9..63377abc2f 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -657,7 +657,8 @@ void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable) bool riscv_cpu_two_stage_lookup(int mmu_idx) { - return mmu_idx & TB_FLAGS_PRIV_HYP_ACCESS_MASK; + return (mmu_idx & TB_FLAGS_PRIV_HYP_ACCESS_MASK) && + (mmu_idx != MMU_IDX_SS_ACCESS); } int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint64_t interrupts) @@ -745,6 +746,38 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv) * preemptive context switch. As a result, do both. */ env->load_res = -1; + + if (cpu_get_bcfien(env) && (env->priv != env->ss_priv)) { + /* + * If backward CFI is enabled in the new privilege state, the + * shadow stack TLB needs to be flushed - unless the most recent + * use of the SS TLB was for the same privilege mode. + */ + tlb_flush_by_mmuidx(env_cpu(env), 1 << MMU_IDX_SS_ACCESS); + /* + * Ignoring env->virt here since currently every time it flips, + * all TLBs are flushed anyway. + */ + env->ss_priv = env->priv; + } +} + +typedef enum { + SSTACK_NO, /* Access is not for a shadow stack instruction */ + SSTACK_YES, /* Access is for a shadow stack instruction */ + SSTACK_DC /* Don't care about SS attribute in PMP */ +} SStackPmpMode; + +static bool legal_sstack_access(int access_type, bool sstack_inst, + bool sstack_attribute) +{ + /* + * Read/write/execution permissions are checked as usual. Shadow + * stack enforcement is just that (1) instruction type must match + * the attribute unless (2) a non-SS load to an SS region. + */ + return (sstack_inst == sstack_attribute) || + ((access_type == MMU_DATA_LOAD) && sstack_attribute); } /* @@ -764,7 +797,7 @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv) static int get_physical_address_pmp(CPURISCVState *env, int *prot, target_ulong *tlb_size, hwaddr addr, int size, MMUAccessType access_type, - int mode) + int mode, SStackPmpMode sstack) { pmp_priv_t pmp_priv; int pmp_index = -1; @@ -812,13 +845,16 @@ static int get_physical_address_pmp(CPURISCVState *env, int *prot, * Second stage is used for hypervisor guest translation * @two_stage: Are we going to perform two stage translation * @is_debug: Is this access from a debugger or the monitor? + * @sstack: Is this access for a shadow stack? Passed by reference so + it can be forced to SSTACK_DC when the SS check is completed + based on a PTE - so the PMP SS attribute will be ignored. */ static int get_physical_address(CPURISCVState *env, hwaddr *physical, int *prot, target_ulong addr, target_ulong *fault_pte_addr, int access_type, int mmu_idx, bool first_stage, bool two_stage, - bool is_debug) + bool is_debug, SStackPmpMode *sstack) { /* NOTE: the env->pc value visible here will not be * correct, but the value visible to the exception handler @@ -830,6 +866,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical, hwaddr ppn; RISCVCPU *cpu = env_archcpu(env); int napot_bits = 0; + bool is_sstack = (sstack != NULL) && (*sstack == SSTACK_YES); target_ulong napot_mask; /* @@ -851,6 +888,8 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical, if (get_field(env->mstatus, MSTATUS_MPRV)) { mode = get_field(env->mstatus, MSTATUS_MPP); } + } else if (mmu_idx == MMU_IDX_SS_ACCESS) { + mode = env->priv; } if (first_stage == false) { @@ -966,7 +1005,7 @@ restart: int vbase_ret = get_physical_address(env, &vbase, &vbase_prot, base, NULL, MMU_DATA_LOAD, mmu_idx, false, true, - is_debug); + is_debug, NULL); if (vbase_ret != TRANSLATE_SUCCESS) { if (fault_pte_addr) { @@ -983,7 +1022,7 @@ restart: int pmp_prot; int pmp_ret = get_physical_address_pmp(env, &pmp_prot, NULL, pte_addr, sizeof(target_ulong), - MMU_DATA_LOAD, PRV_S); + MMU_DATA_LOAD, PRV_S, SSTACK_NO); if (pmp_ret != TRANSLATE_SUCCESS) { return TRANSLATE_PMP_FAIL; } @@ -1010,6 +1049,18 @@ restart: } } + /* + * When backward CFI is enabled, the R=0, W=1, X=0 reserved encoding + * is used to mark Shadow Stack (SS) pages. If back CFI enabled, allow + * normal loads on SS pages, regular stores raise store access fault + * and avoid hitting the reserved-encoding case. Only shadow stack + * stores are allowed on SS pages. Shadow stack loads and stores on + * regular memory (non-SS) raise load and store/AMO access fault. + * Second stage translations don't participate in Shadow Stack. + */ + bool sstack_page = (cpu_get_bcfien(env) && first_stage && + ((pte & (PTE_R | PTE_W | PTE_X)) == PTE_W)); + if (!(pte & PTE_V)) { /* Invalid PTE */ return TRANSLATE_FAIL; @@ -1021,7 +1072,7 @@ restart: return TRANSLATE_FAIL; } base = ppn << PGSHIFT; - } else if ((pte & (PTE_R | PTE_W | PTE_X)) == PTE_W) { + } else if (((pte & (PTE_R | PTE_W | PTE_X)) == PTE_W) && !sstack_page) { /* Reserved leaf PTE flags: PTE_W */ return TRANSLATE_FAIL; } else if ((pte & (PTE_R | PTE_W | PTE_X)) == (PTE_W | PTE_X)) { @@ -1038,16 +1089,21 @@ restart: } else if (ppn & ((1ULL << ptshift) - 1)) { /* Misaligned PPN */ return TRANSLATE_FAIL; - } else if (access_type == MMU_DATA_LOAD && !((pte & PTE_R) || - ((pte & PTE_X) && mxr))) { + } else if (access_type == MMU_DATA_LOAD && !(((pte & PTE_R) || + sstack_page) || ((pte & PTE_X) && mxr))) { /* Read access check failed */ return TRANSLATE_FAIL; - } else if (access_type == MMU_DATA_STORE && !(pte & PTE_W)) { + } else if ((access_type == MMU_DATA_STORE && !is_sstack) && + !(pte & PTE_W)) { /* Write access check failed */ return TRANSLATE_FAIL; } else if (access_type == MMU_INST_FETCH && !(pte & PTE_X)) { /* Fetch access check failed */ return TRANSLATE_FAIL; + } else if (!legal_sstack_access(access_type, is_sstack, + sstack_page)) { + /* Illegal combo of instruction type and page attribute */ + return TRANSLATE_PMP_FAIL; } else { /* if necessary, set accessed and dirty bits. */ target_ulong updated_pte = pte | PTE_A | @@ -1107,18 +1163,27 @@ restart: ) << PGSHIFT) | (addr & ~TARGET_PAGE_MASK); /* set permissions on the TLB entry */ - if ((pte & PTE_R) || ((pte & PTE_X) && mxr)) { + if ((pte & PTE_R) || ((pte & PTE_X) && mxr) || sstack_page) { *prot |= PAGE_READ; } if ((pte & PTE_X)) { *prot |= PAGE_EXEC; } - /* add write permission on stores or if the page is already dirty, - so that we TLB miss on later writes to update the dirty bit */ + /* + * add write permission on stores or if the page is already dirty, + * so that we TLB miss on later writes to update the dirty bit + */ if ((pte & PTE_W) && (access_type == MMU_DATA_STORE || (pte & PTE_D))) { *prot |= PAGE_WRITE; } + if (sstack) { + /* + * Tell the caller to skip the SS bit in the PMP since we + * resolved the attributes via the page table. + */ + *sstack = SSTACK_DC; + } return TRANSLATE_SUCCESS; } } @@ -1190,13 +1255,13 @@ hwaddr riscv_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) int mmu_idx = cpu_mmu_index(&cpu->env, false); if (get_physical_address(env, &phys_addr, &prot, addr, NULL, 0, mmu_idx, - true, riscv_cpu_virt_enabled(env), true)) { + true, riscv_cpu_virt_enabled(env), true, NULL)) { return -1; } if (riscv_cpu_virt_enabled(env)) { if (get_physical_address(env, &phys_addr, &prot, phys_addr, NULL, - 0, mmu_idx, false, true, true)) { + 0, mmu_idx, false, true, true, NULL)) { return -1; } } @@ -1291,6 +1356,8 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, bool two_stage_indirect_error = false; int ret = TRANSLATE_FAIL; int mode = mmu_idx; + bool sstack = (mmu_idx == MMU_IDX_SS_ACCESS); + SStackPmpMode ssmode = sstack ? SSTACK_YES : SSTACK_NO; /* default TLB page size */ target_ulong tlb_size = TARGET_PAGE_SIZE; @@ -1318,7 +1385,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, /* Two stage lookup */ ret = get_physical_address(env, &pa, &prot, address, &env->guest_phys_fault_addr, access_type, - mmu_idx, true, true, false); + mmu_idx, true, true, false, &ssmode); /* * A G-stage exception may be triggered during two state lookup. @@ -1342,7 +1409,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, ret = get_physical_address(env, &pa, &prot2, im_address, NULL, access_type, mmu_idx, false, true, - false); + false, NULL); qemu_log_mask(CPU_LOG_MMU, "%s 2nd-stage address=%" VADDR_PRIx " ret %d physical " @@ -1353,7 +1420,8 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, if (ret == TRANSLATE_SUCCESS) { ret = get_physical_address_pmp(env, &prot_pmp, &tlb_size, pa, - size, access_type, mode); + size, access_type, mode, + SSTACK_NO); qemu_log_mask(CPU_LOG_MMU, "%s PMP address=" HWADDR_FMT_plx " ret %d prot" @@ -1377,7 +1445,8 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, } else { /* Single stage lookup */ ret = get_physical_address(env, &pa, &prot, address, NULL, - access_type, mmu_idx, true, false, false); + access_type, mmu_idx, true, false, + false, &ssmode); qemu_log_mask(CPU_LOG_MMU, "%s address=%" VADDR_PRIx " ret %d physical " @@ -1386,7 +1455,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, if (ret == TRANSLATE_SUCCESS) { ret = get_physical_address_pmp(env, &prot_pmp, &tlb_size, pa, - size, access_type, mode); + size, access_type, mode, ssmode); qemu_log_mask(CPU_LOG_MMU, "%s PMP address=" HWADDR_FMT_plx " ret %d prot" From patchwork Thu Feb 9 06:29:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Deepak Gupta X-Patchwork-Id: 1739820 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=rivosinc-com.20210112.gappssmtp.com header.i=@rivosinc-com.20210112.gappssmtp.com header.a=rsa-sha256 header.s=20210112 header.b=EHhumVzD; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4PC6WK3G1Fz23jH for ; Thu, 9 Feb 2023 17:33:17 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pQ0SQ-0007k8-GH; Thu, 09 Feb 2023 01:30:58 -0500 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 1pQ0S2-0007YO-31 for qemu-devel@nongnu.org; Thu, 09 Feb 2023 01:30:34 -0500 Received: from mail-pg1-x533.google.com ([2607:f8b0:4864:20::533]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pQ0S0-0000jX-0c for qemu-devel@nongnu.org; Thu, 09 Feb 2023 01:30:33 -0500 Received: by mail-pg1-x533.google.com with SMTP id 24so936914pgt.7 for ; Wed, 08 Feb 2023 22:30:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20210112.gappssmtp.com; s=20210112; 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=TofwhUrqur+nfz+vYUg5s7uS+g1axympVTaiH26ziSo=; b=EHhumVzDciJDtBOM4uqAKPsy2YjiZ44T7DJBiVN0Qk7baGOaJJf1XBqIESAzuKUqid lnJrR8ubx2dNM1Bup32Pb0DkXXYUayLpmwX1J0/p5TQhgyBUU39D3LR+dTmfwXuoGE5J lPn0GLbtR1B18Sw7VFlr8Q/QtrlT4yyFqFEwQtZVCkoSh8wikYnE7QyY7tKcaWdFE/uE tQRne0hW17ghts6U7XtMP/W9VHFW2bxAoR9A489/bgErJyzL2Vsmt+p+vgIEV2cIHzEy 4Yxq3ah7kiGEy/u8uCOiISyLe138H7OxvzIO9Z5QD/Jw1qsrsj4ZAOPBPIhNTy+Y3MVt s1Fg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=TofwhUrqur+nfz+vYUg5s7uS+g1axympVTaiH26ziSo=; b=0p1/FNBunCSvn32Q+y56AedwIyUdB/7qG0epFwWc6lO77l7LhsL2ZcccAGd40OX/lQ /WJptg8TTC+KWtTRErqPrHfUJTceRjRe4gOqHAC0RfrOyqvb1CZ8efjgzdkMTtpKiuhg 6ExEMtPloeQW4foyEQDCSJzFq971G+pVelwWWiudQJi5Jxqr+0Kwq9oA9ndY6dpSYcMS 8C9+gGW/w7pk0pdVT4QSAUMWhQWjA+6/8Tg7c+hyjtp3GJ7zEvAvHCd/dqnAgcMFJYdD N0PI+lyUxDB7VOP/di3CxtIfTvH7FVIDP0OWOf6rbshrBMjSbnqCRERVyLgs33Xo6PM5 4HnA== X-Gm-Message-State: AO0yUKWR2I47g4o11vtwtgzTCsmoolhOSlabOgibP9V72czDIAKV+kxS XEGUljLY8qFmdG4KV1eEFUq3pPdDIGAbOsez X-Google-Smtp-Source: AK7set/cyIZgNCxvo7M/OYJYSUxwE3yk8syJYNMLCVrixfj1cWHCDbPHlr3PWIBHvxJvx0hsld+s7Q== X-Received: by 2002:aa7:9575:0:b0:5a8:4861:af7d with SMTP id x21-20020aa79575000000b005a84861af7dmr4237442pfq.20.1675924230864; Wed, 08 Feb 2023 22:30:30 -0800 (PST) Received: from debug.ba.rivosinc.com ([66.220.2.162]) by smtp.gmail.com with ESMTPSA id u15-20020aa7848f000000b00593c434b1b8sm543649pfn.48.2023.02.08.22.30.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 08 Feb 2023 22:30:30 -0800 (PST) From: Deepak Gupta To: qemu-devel@nongnu.org, Palmer Dabbelt , Alistair Francis , Bin Meng Cc: Deepak Gupta , Kip Walker , qemu-riscv@nongnu.org Subject: [PATCH v1 RFC Zisslpcfi 7/9] target/riscv: Tracking indirect branches (fcfi) using TCG Date: Wed, 8 Feb 2023 22:29:45 -0800 Message-Id: <20230209062947.3585481-8-debug@rivosinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230209062947.3585481-1-debug@rivosinc.com> References: <20230209062947.3585481-1-debug@rivosinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::533; envelope-from=debug@rivosinc.com; helo=mail-pg1-x533.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 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+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org zisslpcfi protects forward control flow (if enabled) by enforcing all indirect call and jmp must land on a landing pad instruction `lpcll` short for landing pad and check lower label value. If target of an indirect call or jmp is not `lpcll` then cpu/hart must raise an illegal instruction exception. This patch implements the mechanism using TCG. Target architecture branch instruction must define the end of a TB. Using this property, during translation of branch instruction, TB flag = FCFI_LP_EXPECTED can be set. Translation of target TB can check if FCFI_LP_EXPECTED flag is set and a flag (fcfi_lp_expected) can be set in DisasContext. If `lpcll` gets translated, fcfi_lp_expected flag in DisasContext can be cleared. Else it'll fault. This patch also also adds flag for forward and backward cfi in DisasContext. Signed-off-by: Deepak Gupta Signed-off-by: Kip Walker --- target/riscv/cpu.h | 3 +++ target/riscv/cpu_helper.c | 12 +++++++++ target/riscv/translate.c | 52 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 8803ea6426..98b272bcad 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -644,6 +644,9 @@ FIELD(TB_FLAGS, VMA, 25, 1) /* Native debug itrigger */ FIELD(TB_FLAGS, ITRIGGER, 26, 1) +/* Zisslpcfi needs a TB flag to track indirect branches */ +FIELD(TB_FLAGS, FCFI_LP_EXPECTED, 27, 1) + #ifdef TARGET_RISCV32 #define riscv_cpu_mxl(env) ((void)(env), MXL_RV32) #else diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 63377abc2f..d15918f534 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -129,6 +129,18 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc, flags = FIELD_DP32(flags, TB_FLAGS, VILL, 1); } + if (cpu->cfg.ext_cfi) { + /* + * For Forward CFI, only the expectation of a lpcll at + * the start of the block is tracked (which can only happen + * when FCFI is enabled for the current processor mode). A jump + * or call at the end of the previous TB will have updated + * env->elp to indicate the expectation. + */ + flags = FIELD_DP32(flags, TB_FLAGS, FCFI_LP_EXPECTED, + env->elp != NO_LP_EXPECTED); + } + #ifdef CONFIG_USER_ONLY flags |= TB_FLAGS_MSTATUS_FS; flags |= TB_FLAGS_MSTATUS_VS; diff --git a/target/riscv/translate.c b/target/riscv/translate.c index df38db7553..7d43d20fc3 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -41,6 +41,7 @@ static TCGv load_val; /* globals for PM CSRs */ static TCGv pm_mask; static TCGv pm_base; +static TCGOp *cfi_lp_check; #include "exec/gen-icount.h" @@ -116,6 +117,10 @@ typedef struct DisasContext { bool itrigger; /* TCG of the current insn_start */ TCGOp *insn_start; + /* CFI extension */ + bool bcfi_enabled; + bool fcfi_enabled; + bool fcfi_lp_expected; } DisasContext; static inline bool has_ext(DisasContext *ctx, uint32_t ext) @@ -1166,11 +1171,44 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) ctx->pm_mask_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_MASK_ENABLED); ctx->pm_base_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_BASE_ENABLED); ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER); + ctx->bcfi_enabled = cpu_get_bcfien(env); + ctx->fcfi_enabled = cpu_get_fcfien(env); + ctx->fcfi_lp_expected = FIELD_EX32(tb_flags, TB_FLAGS, FCFI_LP_EXPECTED); ctx->zero = tcg_constant_tl(0); } static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu) { + DisasContext *ctx = container_of(db, DisasContext, base); + + if (ctx->fcfi_lp_expected) { + /* + * Since we can't look ahead to confirm that the first + * instruction is a legal landing pad instruction, emit + * compare-and-branch sequence that will be fixed-up in + * riscv_tr_tb_stop() to either statically hit or skip an + * illegal instruction exception depending on whether the + * flag was lowered by translation of a CJLP or JLP as + * the first instruction in the block. + */ + TCGv_i32 immediate; + TCGLabel *l; + l = gen_new_label(); + immediate = tcg_temp_local_new_i32(); + tcg_gen_movi_i32(immediate, 0); + cfi_lp_check = tcg_last_op(); + tcg_gen_brcondi_i32(TCG_COND_EQ, immediate, 0, l); + tcg_temp_free_i32(immediate); + gen_exception_illegal(ctx); + gen_set_label(l); + /* + * Despite the use of gen_exception_illegal(), the rest of + * the TB needs to be generated. The TCG optimizer will + * clean things up depending on which path ends up being + * active. + */ + ctx->base.is_jmp = DISAS_NEXT; + } } static void riscv_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu) @@ -1225,6 +1263,7 @@ static void riscv_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) static void riscv_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) { DisasContext *ctx = container_of(dcbase, DisasContext, base); + CPURISCVState *env = cpu->env_ptr; switch (ctx->base.is_jmp) { case DISAS_TOO_MANY: @@ -1235,6 +1274,19 @@ static void riscv_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) default: g_assert_not_reached(); } + + if (ctx->fcfi_lp_expected) { + /* + * If the "lp expected" flag is still up, the block needs to take an + * illegal instruction exception. + */ + tcg_set_insn_param(cfi_lp_check, 1, tcgv_i32_arg(tcg_constant_i32(1))); + } else { + /* + * LP instruction requirement was met, clear up LP expected + */ + env->elp = NO_LP_EXPECTED; + } } static void riscv_tr_disas_log(const DisasContextBase *dcbase, From patchwork Thu Feb 9 06:29:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Deepak Gupta X-Patchwork-Id: 1739816 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=rivosinc-com.20210112.gappssmtp.com header.i=@rivosinc-com.20210112.gappssmtp.com header.a=rsa-sha256 header.s=20210112 header.b=j+azb1Kz; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4PC6Tl6Vwzz23jH for ; Thu, 9 Feb 2023 17:31:55 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pQ0SU-0007q9-Eo; Thu, 09 Feb 2023 01:31:02 -0500 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 1pQ0S5-0007Yy-2O for qemu-devel@nongnu.org; Thu, 09 Feb 2023 01:30:39 -0500 Received: from mail-pg1-x529.google.com ([2607:f8b0:4864:20::529]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pQ0S2-0000nV-7m for qemu-devel@nongnu.org; Thu, 09 Feb 2023 01:30:36 -0500 Received: by mail-pg1-x529.google.com with SMTP id a23so915288pga.13 for ; Wed, 08 Feb 2023 22:30:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20210112.gappssmtp.com; s=20210112; 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=9Jpx55XSl5ZxIppesj8mRIonMpJl9Kp5E0HS//vv/Ps=; b=j+azb1Kz/1+LoMUMSplcOtGgQhwxIguegMsgcMARZa9pws3BV5KeFtOfIiZxSBsrP4 zyKSPRMA/9Q/5fDN0daNctWKH3IGJH0yrDfSN/VCDvn6uEWM8VybsLF/Hj+WIKZZajr1 oCyr5oK4xEn0m/9mQtqoWPNA1BbqO/yX7IfbokLyJANL5hOB8ktFN/1JRS/fHR7wFB2y 32idjuTaN3vFydVVG/DkaUUP6ZSqW6ytS0XKj1h1aE+YBmDbb0NFTAQ9hMWn3sJBlQcR v78tXLYcL5dQDVkAbB9wZruo6Fh1Oq+uLE1Nm8OQeLWwkAXSbm9hufXaDn7Fmk80vtrn rjWA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=9Jpx55XSl5ZxIppesj8mRIonMpJl9Kp5E0HS//vv/Ps=; b=uHM13r5WFsXG+eL0KVY63AsfkxfOtL3VsuSj/x+H6rQaz0x5IyUr1kgzHxvG0WABdz TujBQoxsml+3rN43eenIE+zqwQVKyJEgMCEROLhEAGlHKPPaajAN3LgOKmxRxJ1dJ1c6 ktgcDZ9EnXWK6NmwXVZtibdK8cHFnycgLKcmCngZVS2cVOWGi8J9uSaSX1KT/SDesJDo 23RBwoWpuZt9R5tv3qknjv44beq3Q+DBHc5FPCWIBmCaLMnoiJbjZCjKeuSNFC/5c2oy gUMrwl7pdpGUuz+3Llb7NaaP18JwzzFEn1HugalmCReg6yc4543EJkcywKkFRRMaE6tI x2Hw== X-Gm-Message-State: AO0yUKUgK3ANBiqpTllQ9YSzSoTKxXqJmjux1h8LDsU/6o9dtCTvdau0 sfHJStqg8dt9NtToCD6o5W1EFjHcM4rqNN9b X-Google-Smtp-Source: AK7set8f6Mr+6M2Ck3Fgqx++ypnlj255d4fG6kx+KRgA4hQvhUnrDithtp9Ix9UbZZEh79h9aCA96A== X-Received: by 2002:aa7:9aca:0:b0:592:61e2:f598 with SMTP id x10-20020aa79aca000000b0059261e2f598mr10054923pfp.26.1675924232146; Wed, 08 Feb 2023 22:30:32 -0800 (PST) Received: from debug.ba.rivosinc.com ([66.220.2.162]) by smtp.gmail.com with ESMTPSA id u15-20020aa7848f000000b00593c434b1b8sm543649pfn.48.2023.02.08.22.30.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 08 Feb 2023 22:30:31 -0800 (PST) From: Deepak Gupta To: qemu-devel@nongnu.org, Palmer Dabbelt , Alistair Francis , Bin Meng Cc: Deepak Gupta , Kip Walker , qemu-riscv@nongnu.org Subject: [PATCH v1 RFC Zisslpcfi 8/9] target/riscv: Instructions encodings, implementation and handlers Date: Wed, 8 Feb 2023 22:29:46 -0800 Message-Id: <20230209062947.3585481-9-debug@rivosinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230209062947.3585481-1-debug@rivosinc.com> References: <20230209062947.3585481-1-debug@rivosinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::529; envelope-from=debug@rivosinc.com; helo=mail-pg1-x529.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 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+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org This patch implements instruction encodings for zisslpcfi instructions. Additionally this patch implements zimops encodings as well. If Zisslpcfi is supported by CPU but not enabled then all Zisslpcfi instructions default to Zimops instuction behavior i.e. mov 0 to rd. zisslpcfi defines following instructions. - Backward control flow - sspush x1/x5 : Decrement shadow stack pointer and pushes x1 or x5 on shadow stack. - sspop x1/x5 : Pops from shadow stack into x1 or x5. Increments shadow stack pointer. - ssprr : Reads current shadow stack pointer into a destination register. - sscheckra : Compares x1 with x5. Raises illegal instr fault if x1 != x5 - ssamoswap : Atomically swaps value on top of shadow stack - Forward control flow - lpsll, lpsml, lpsul : sets lower (9bit), mid (8bit) and upper (8bit) label values in CSR_ULLP respectively. - lpcll, lpcml, lpcul : checks lower (9bit), mid (8bit) and upper (8bit) label values with CSR_ULLP respectively. Check label instructions raise illegal instruction fault when labels mismatch. Signed-off-by: Deepak Gupta Signed-off-by: Kip Walker --- target/riscv/cpu_bits.h | 10 + target/riscv/helper.h | 7 + target/riscv/insn32.decode | 29 ++ target/riscv/insn_trans/trans_rvi.c.inc | 14 + target/riscv/insn_trans/trans_zimops.c.inc | 53 +++ target/riscv/insn_trans/trans_zisslpcfi.c.inc | 310 ++++++++++++++++++ target/riscv/op_helper.c | 67 ++++ target/riscv/translate.c | 2 + 8 files changed, 492 insertions(+) create mode 100644 target/riscv/insn_trans/trans_zimops.c.inc create mode 100644 target/riscv/insn_trans/trans_zisslpcfi.c.inc diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h index 37100ec8f6..b2d527c626 100644 --- a/target/riscv/cpu_bits.h +++ b/target/riscv/cpu_bits.h @@ -600,6 +600,16 @@ typedef enum { LP_EXPECTED = 1, } cfi_elp; +#define LPLR_UL (((1 << 8) - 1) << 17) +#define LPLR_ML (((1 << 8) - 1) << 9) +#define LPLR_LL ((1 << 9) - 1) + +typedef enum { + FCFI_LPLL = 0, + FCFI_ML = 1, + FCFI_UL = 2, +} cfi_label_inst; + /* hstatus CSR bits */ #define HSTATUS_VSBE 0x00000020 #define HSTATUS_GVA 0x00000040 diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 227c7122ef..6484415612 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -97,6 +97,11 @@ DEF_HELPER_FLAGS_2(fcvt_h_l, TCG_CALL_NO_RWG, i64, env, tl) DEF_HELPER_FLAGS_2(fcvt_h_lu, TCG_CALL_NO_RWG, i64, env, tl) DEF_HELPER_FLAGS_2(fclass_h, TCG_CALL_NO_RWG_SE, tl, env, i64) +/* Forward CFI label checking */ +DEF_HELPER_2(cfi_jalr, void, env, int) +DEF_HELPER_3(cfi_check_landing_pad, void, env, int, int) +DEF_HELPER_3(cfi_set_landing_pad, void, env, int, int) + /* Special functions */ DEF_HELPER_2(csrr, tl, env, int) DEF_HELPER_3(csrw, void, env, int, tl) @@ -112,6 +117,8 @@ DEF_HELPER_1(tlb_flush, void, env) /* Native Debug */ DEF_HELPER_1(itrigger_match, void, env) #endif +/* helper for back cfi mismatch */ +DEF_HELPER_1(sschkra_mismatch, void, env) /* Hypervisor functions */ #ifndef CONFIG_USER_ONLY diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index b7e7613ea2..cd734f03ae 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -37,6 +37,8 @@ %imm_u 12:s20 !function=ex_shift_12 %imm_bs 30:2 !function=ex_shift_3 %imm_rnum 20:4 +%imm_cfi9 15:9 +%imm_cfi8 15:8 # Argument sets: &empty @@ -163,6 +165,33 @@ csrrwi ............ ..... 101 ..... 1110011 @csr csrrsi ............ ..... 110 ..... 1110011 @csr csrrci ............ ..... 111 ..... 1110011 @csr +# zimops (unpriv integer may be operations) instructions with system opcode +# These're superset of for cfi encodings. zimops_r and zimops_rr should be last +# entry in below overlapping patterns so that it acts as final sink for overlapping patterns. +# Any new encoding that can be used should be placed above mop.r and mop.rr + +# cfi instructions carved out of mop.r +{ + sspush 100000 0 11100 ..... 100 00000 1110011 %rs1 + sspop 100000 0 11100 00000 100 ..... 1110011 %rd + ssprr 100000 0 11101 00000 100 ..... 1110011 %rd + zimops_r 1-00-- 0 111-- ----- 100 ..... 1110011 %rd +} + +# cfi instructions carved out of mop.rr +{ + sschckra 100010 1 00001 00101 100 00000 1110011 + ssamoswap 100000 1 ..... ..... 100 ..... 1110011 @r + + lpsll 100000 1 0 ......... 100 00000 1110011 %imm_cfi9 + lpcll 100000 1 1 ......... 100 00000 1110011 %imm_cfi9 + lpsml 100001 1 0 0........ 100 00000 1110011 %imm_cfi8 + lpcml 100001 1 0 1........ 100 00000 1110011 %imm_cfi8 + lpsul 100010 1 1 0........ 100 00000 1110011 %imm_cfi8 + lpcul 100010 1 1 1........ 100 00000 1110011 %imm_cfi8 + zimops_rr 1-00-- 1 - --------- 100 ..... 1110011 %rd +} + # *** RV64I Base Instruction Set (in addition to RV32I) *** lwu ............ ..... 110 ..... 0000011 @i ld ............ ..... 011 ..... 0000011 @i diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc index 5c69b88d1e..4a4f1ca778 100644 --- a/target/riscv/insn_trans/trans_rvi.c.inc +++ b/target/riscv/insn_trans/trans_rvi.c.inc @@ -66,6 +66,20 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a) } gen_set_gpri(ctx, a->rd, ctx->pc_succ_insn); + + if (ctx->cfg_ptr->ext_cfi) { + /* + * Rely on a helper to check the forward CFI enable for the + * current process mode. The alternatives would be (1) include + * "fcfi enabled" in the cflags or (2) maintain a "fcfi + * currently enabled" in cpu_env and emit TCG code to access + * and test it. + */ + if (a->rd == xRA || a->rd == xT0 || (a->rs1 != xRA && a->rs1 != xT0)) { + gen_helper_cfi_jalr(cpu_env, tcg_constant_i32(LP_EXPECTED)); + } + } + lookup_and_goto_ptr(ctx); if (misaligned) { diff --git a/target/riscv/insn_trans/trans_zimops.c.inc b/target/riscv/insn_trans/trans_zimops.c.inc new file mode 100644 index 0000000000..51748637b9 --- /dev/null +++ b/target/riscv/insn_trans/trans_zimops.c.inc @@ -0,0 +1,53 @@ +/* + * RISC-V translation routines for the Control-Flow Integrity Extension + * + * Copyright (c) 2022-2023 Rivos Inc. + * + * 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 . + */ + + static bool trans_zimops_r(DisasContext *ctx, arg_zimops_r * a) + { + /* zimops not implemented, raise illegal instruction & return true */ + if (!ctx->cfg_ptr->ext_zimops) { + gen_exception_illegal(ctx); + return true; + } + + /* + * zimops implemented, simply grab destination and mov zero. + * return true + */ + TCGv dest = dest_gpr(ctx, a->rd); + dest = tcg_const_tl(0); + gen_set_gpr(ctx, a->rd, dest); + return true; + } + + static bool trans_zimops_rr(DisasContext *ctx, arg_zimops_rr * a) + { + /* zimops not implemented, raise illegal instruction & return true */ + if (!ctx->cfg_ptr->ext_zimops) { + gen_exception_illegal(ctx); + return true; + } + + /* + * zimops implemented, simply grab destination and mov zero. + * return true + */ + TCGv dest = dest_gpr(ctx, a->rd); + dest = tcg_const_tl(0); + gen_set_gpr(ctx, a->rd, dest); + return true; + } diff --git a/target/riscv/insn_trans/trans_zisslpcfi.c.inc b/target/riscv/insn_trans/trans_zisslpcfi.c.inc new file mode 100644 index 0000000000..fe27bb73f6 --- /dev/null +++ b/target/riscv/insn_trans/trans_zisslpcfi.c.inc @@ -0,0 +1,310 @@ +/* + * RISC-V translation routines for the Control-Flow Integrity Extension + * + * Copyright (c) 2022-2023 Rivos Inc. + * + * 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 . + */ + +static MemOp mxl_memop(DisasContext *ctx) +{ + switch (get_xl(ctx)) { + case MXL_RV32: + return MO_TEUL; + + case MXL_RV64: + return MO_TEUQ; + + case MXL_RV128: + return MO_TEUO; + + default: + g_assert_not_reached(); + } +} + +static bool trans_sspop(DisasContext *ctx, arg_sspop *a) +{ + /* cfi only supported on 32bit and 64bit */ + if (get_xl(ctx) != MXL_RV32 && get_xl(ctx) != MXL_RV64) { + return false; + } + + /* back cfi not enabled, should go to trans_zimops. return false */ + if (!ctx->bcfi_enabled) { + return false; + } + + /* sspop can only load into x1 or x5. Everything else defaults to zimops */ + if (a->rd != 1 && a->rd != 5) { + return false; + } + + /* + * get data in TCGv using get_gpr + * get addr in TCGv using gen_helper_csrr on CSR_SSP + * use some tcg subtract arithmetic (subtract by XLEN) on addr + * perform ss store on computed address + */ + + TCGv addr = tcg_temp_new(); + int tmp = (get_xl(ctx) == MXL_RV64) ? 8 : 4; + TCGv_i32 ssp_csr = tcg_constant_i32(CSR_SSP); + TCGv data = get_gpr(ctx, a->rd, EXT_NONE); + gen_helper_csrr(addr, cpu_env, ssp_csr); + tcg_gen_qemu_ld_tl(data, addr, MMU_IDX_SS_ACCESS, + mxl_memop(ctx) | MO_ALIGN); + + /* + * add XLEN/bitwidth to addr, align to XLEN . How do i do that? Is below + * the right way + */ + tcg_gen_addi_tl(addr, addr, tmp); + gen_set_gpr(ctx, a->rd, data); + gen_helper_csrw(cpu_env, ssp_csr, addr); + + return true; +} + +static bool trans_sspush(DisasContext *ctx, arg_sspush *a) +{ + /* cfi only supported on 32bit and 64bit */ + if (get_xl(ctx) != MXL_RV32 && get_xl(ctx) != MXL_RV64) { + return false; + } + + /* back cfi not enabled, should go to trans_zimops. return false */ + if (!ctx->bcfi_enabled) { + return false; + } + + /* + * sspush can only push from x1 or x5. Everything else defaults to zimops + */ + if (a->rs1 != 1 && a->rs1 != 5) { + return false; + } + + /* + * get data in TCGv using get_gpr + * get addr in TCGv using gen_helper_csrr on CSR_SSP + * use some tcg subtract arithmetic (subtract by XLEN) on addr + * perform ss store on computed address + */ + + TCGv addr = tcg_temp_new(); + int tmp = (get_xl(ctx) == MXL_RV64) ? -8 : -4; + TCGv_i32 ssp_csr = tcg_constant_i32(CSR_SSP); + TCGv data = get_gpr(ctx, a->rs1, EXT_NONE); + gen_helper_csrr(addr, cpu_env, ssp_csr); + + /* + * subtract XLEN from addr, align to XLEN . How do i do that? Is below the + * right way + */ + tcg_gen_addi_tl(addr, addr, tmp); + tcg_gen_qemu_st_tl(data, addr, MMU_IDX_SS_ACCESS, + mxl_memop(ctx) | MO_ALIGN); + + gen_helper_csrw(cpu_env, ssp_csr, addr); + + return true; +} + +static bool trans_sschckra(DisasContext *ctx, arg_sschckra *a) +{ + /* cfi only supported on 32bit and 64bit */ + if (get_xl(ctx) != MXL_RV32 && get_xl(ctx) != MXL_RV64) { + return false; + } + + /* back cfi not enabled, should go to trans_zimops. return false */ + if (!ctx->bcfi_enabled) { + return false; + } + + gen_helper_sschkra_mismatch(cpu_env); + + return true; +} + +static bool trans_ssprr(DisasContext *ctx, arg_ssprr *a) +{ + /* cfi only supported on 32bit and 64bit */ + if (get_xl(ctx) != MXL_RV32 && get_xl(ctx) != MXL_RV64) { + return false; + } + + /* back cfi not enabled, should go to trans_zimops. return false */ + if (!ctx->bcfi_enabled) { + return false; + } + + TCGv dest = get_gpr(ctx, a->rd, EXT_NONE); + TCGv_i32 ssp_csr = tcg_constant_i32(CSR_SSP); + gen_helper_csrr(dest, cpu_env, ssp_csr); + gen_set_gpr(ctx, a->rd, dest); + + return true; +} + +static bool trans_ssamoswap(DisasContext *ctx, arg_ssamoswap *a) +{ + /* cfi only supported on 32bit and 64bit */ + if (get_xl(ctx) != MXL_RV32 && get_xl(ctx) != MXL_RV64) { + return false; + } + + /* back cfi not enabled, should go to trans_zimops. return false */ + if (!ctx->bcfi_enabled) { + return false; + } + + /* If cfi is enabled then, then rd must be != 0 */ + + if (a->rd == 0) { + return false; + } + + TCGv dest = dest_gpr(ctx, a->rd); + TCGv src1 = get_address(ctx, a->rs1, 0); + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); + MemOp mop = (MO_ALIGN | ((get_xl(ctx) == MXL_RV32) ? MO_TESL : MO_TESQ)); + + tcg_gen_atomic_xchg_tl(dest, src1, src2, MMU_IDX_SS_ACCESS, mop); + gen_set_gpr(ctx, a->rd, dest); + return true; +} + +static bool trans_lpcll(DisasContext *ctx, arg_lpcll *a) +{ + /* cfi only supported on 32bit and 64bit */ + if (get_xl(ctx) != MXL_RV32 && get_xl(ctx) != MXL_RV64) { + return false; + } + + /* + * If this is the first instruction of the TB, let the translator + * know the landing pad requirement was satisfied. No need to bother + * checking for CFI feature or enablement. + */ + + if (ctx->base.pc_next == ctx->base.pc_first) { + ctx->fcfi_lp_expected = false; + /* PC must be 4 byte aligned */ + if (ctx->fcfi_enabled && ((ctx->base.pc_next) & 0x3)) { + /* + * misaligned, according to spec we should raise illegal instead + * of mis-aligned + */ + gen_exception_illegal(ctx); + } + } + + /* forward cfi not enabled, should go to trans_zimops. return false */ + if (!ctx->fcfi_enabled) { + return false; + } + + gen_helper_cfi_check_landing_pad(cpu_env, tcg_constant_i32(a->imm_cfi9), + tcg_constant_i32(FCFI_LPLL)); + return true; +} + +static bool trans_lpcml(DisasContext *ctx, arg_lpcml *a) +{ + /* cfi only supported on 32bit and 64bit */ + if (get_xl(ctx) != MXL_RV32 && get_xl(ctx) != MXL_RV64) { + return false; + } + + /* forward cfi not enabled, should go to trans_zimops. return false */ + if (!ctx->fcfi_enabled) { + return false; + } + + gen_helper_cfi_check_landing_pad(cpu_env, tcg_constant_i32(a->imm_cfi8), + tcg_constant_i32(FCFI_ML)); + return true; +} + +static bool trans_lpcul(DisasContext *ctx, arg_lpcul *a) +{ + /* cfi only supported on 32bit and 64bit */ + if (get_xl(ctx) != MXL_RV32 && get_xl(ctx) != MXL_RV64) { + return false; + } + + /* forward cfi not enabled, should go to trans_zimops. return false */ + if (!ctx->fcfi_enabled) { + return false; + } + + gen_helper_cfi_check_landing_pad(cpu_env, tcg_constant_i32(a->imm_cfi8), + tcg_constant_i32(FCFI_UL)); + return true; +} + +static bool trans_lpsll(DisasContext *ctx, arg_lpsll *a) +{ + /* cfi only supported on 32bit and 64bit */ + if (get_xl(ctx) != MXL_RV32 && get_xl(ctx) != MXL_RV64) { + return false; + } + + /* forward cfi not enabled, should go to trans_zimops. return false */ + if (!ctx->fcfi_enabled) { + return false; + } + + gen_helper_cfi_set_landing_pad(cpu_env, tcg_constant_i32(a->imm_cfi9), + tcg_constant_i32(FCFI_LPLL)); + + return true; +} + +static bool trans_lpsml(DisasContext *ctx, arg_lpsml *a) +{ + /* cfi only supported on 32bit and 64bit */ + if (get_xl(ctx) != MXL_RV32 && get_xl(ctx) != MXL_RV64) { + return false; + } + + /* forward cfi not enabled, should go to trans_zimops. return false */ + if (!ctx->fcfi_enabled) { + return false; + } + + gen_helper_cfi_set_landing_pad(cpu_env, tcg_constant_i32(a->imm_cfi8), + tcg_constant_i32(FCFI_ML)); + + return true; +} + +static bool trans_lpsul(DisasContext *ctx, arg_lpsul *a) +{ + /* cfi only supported on 32bit and 64bit */ + if (get_xl(ctx) != MXL_RV32 && get_xl(ctx) != MXL_RV64) { + return false; + } + + /* forward cfi not enabled, should go to trans_zimops. return false */ + if (!ctx->fcfi_enabled) { + return false; + } + + gen_helper_cfi_set_landing_pad(cpu_env, tcg_constant_i32(a->imm_cfi8), + tcg_constant_i32(FCFI_UL)); + + return true; +} diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c index d15893aa82..c14b76aabb 100644 --- a/target/riscv/op_helper.c +++ b/target/riscv/op_helper.c @@ -123,6 +123,73 @@ target_ulong helper_csrrw_i128(CPURISCVState *env, int csr, return int128_getlo(rv); } +void helper_sschkra_mismatch(CPURISCVState *env) +{ + if (env->gpr[xRA] != env->gpr[xT0]) { + riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); + } +} + +void helper_cfi_jalr(CPURISCVState *env, int elp) +{ + /* + * The translation routine doesn't know if forward CFI is enabled + * in the current processor mode or not. It's not worth burning a + * cflags bit to encode this, or tracking the current-mode-fcfi + * enable in a dedicated member of 'env'. Just come out to a helper + * for jump/call on a core with CFI. + */ + if (cpu_get_fcfien(env)) { + env->elp = elp; + } +} + +void helper_cfi_check_landing_pad(CPURISCVState *env, int lbl, int inst_type) +{ + if (cpu_get_fcfien(env)) { + switch (inst_type) { + case FCFI_LPLL: + /* + * Check for a lower label match. We already checked 4 byte + * alignment in tcg + */ + if (lbl != get_field(env->lplr, LPLR_LL)) { + riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); + } + env->elp = NO_LP_EXPECTED; + break; + case FCFI_ML: + if (lbl != get_field(env->lplr, LPLR_ML)) { + riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); + } + break; + case FCFI_UL: + if (lbl != get_field(env->lplr, LPLR_UL)) { + riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); + } + } + } +} + +void helper_cfi_set_landing_pad(CPURISCVState *env, int lbl, int inst_type) +{ + if (cpu_get_fcfien(env)) { + switch (inst_type) { + case FCFI_LPLL: + /* setting lower label always clears up entire field */ + env->lplr = 0; + env->lplr = set_field(env->lplr, LPLR_LL, lbl); + break; + case FCFI_ML: + env->lplr = set_field(env->lplr, LPLR_ML, lbl); + break; + case FCFI_UL: + env->lplr = set_field(env->lplr, LPLR_UL, lbl); + break; + } + } +} + #ifndef CONFIG_USER_ONLY target_ulong helper_sret(CPURISCVState *env) diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 7d43d20fc3..b1a965d192 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -1071,6 +1071,8 @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc) #include "insn_trans/trans_privileged.c.inc" #include "insn_trans/trans_svinval.c.inc" #include "insn_trans/trans_xventanacondops.c.inc" +#include "insn_trans/trans_zisslpcfi.c.inc" +#include "insn_trans/trans_zimops.c.inc" /* Include the auto-generated decoder for 16 bit insn */ #include "decode-insn16.c.inc" From patchwork Thu Feb 9 06:29:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Deepak Gupta X-Patchwork-Id: 1739815 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=rivosinc-com.20210112.gappssmtp.com header.i=@rivosinc-com.20210112.gappssmtp.com header.a=rsa-sha256 header.s=20210112 header.b=t30FnQ5H; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4PC6Tg0KMmz23jH for ; Thu, 9 Feb 2023 17:31:51 +1100 (AEDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pQ0SR-0007lP-Hu; Thu, 09 Feb 2023 01:30:59 -0500 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 1pQ0S5-0007Z1-5Q for qemu-devel@nongnu.org; Thu, 09 Feb 2023 01:30:39 -0500 Received: from mail-pl1-x635.google.com ([2607:f8b0:4864:20::635]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1pQ0S3-0000o9-9t for qemu-devel@nongnu.org; Thu, 09 Feb 2023 01:30:36 -0500 Received: by mail-pl1-x635.google.com with SMTP id u9so1833599plf.3 for ; Wed, 08 Feb 2023 22:30:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20210112.gappssmtp.com; s=20210112; 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=rfCWSS9jG8oH/r1HKi/uvLvwEOlj2iUYuI+0QRVQEBI=; b=t30FnQ5HaoX99Ii21dj/N8EtOEur7pO9kAl21LLxS6ZIKV+5LQQLE5xeQvP6dHwmmJ l+lsJ1vvLYcYtAl83J/zUipRUDlnPghks92akgOYzm7KpVcidm3pRWvPg5vS1yH46Vgq jZ9F/eGJHBDWxfON/xRxvBR9lmyBDwKi6mhYZACdUmuK1KLUtqclm1otpq2RbmaEByCX P8G79yBePj+lCluzq8Afodr65BRplaOe4C2ECTpzAX08RxcviyPjjiaiqY8XEQR0rcox o4f4DU/naRLlP7C37fAX3KbXtD8LqjQar7KWotODi8/ZJ6S1cx4XHe+V7pl2llzY3Y+D WMsA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=rfCWSS9jG8oH/r1HKi/uvLvwEOlj2iUYuI+0QRVQEBI=; b=JbXqGrkT02BEBs/ffIDIhOnLcydHdIcfFOkh8o6Qfhxn+HqPwek7HGW5ciWyGECdo4 AT59y7vzQcIgII6887hzy+p+pr7EJCtPAuMK1Bifz8Ae75QXxNFvOW6V2mM6yoJ6h8lf W4MFBIKZfEs+++SNo69PlLpoX51DfvB7PycdHatmQVYvXua+GfeJYwPOERHH5Lrckwat VMPmSdd5OTkCDmTqqEB/lrnw7d5ROaRMyyqWkTqnL/LGbU2/Tj1mvn5y0A9Wiz1aCuD4 MqrcKS+gTCBxDwMx9VyafNIMSEhmdjdA/JYzijuECihBAgWVgvOUGFmhebDj3ZEg066T znvA== X-Gm-Message-State: AO0yUKUSgt0NtHTzguHCwK9qGBYtpj9Kbl+1irCUMqTqLjzB3/nqAMdV JkThGo5EeQR1Km7I4LqbBavn5bKAx4VpXWQB X-Google-Smtp-Source: AK7set//WQjnVauFQMciSD7aXuLNtoDl91A1cwqGpHfe7qe75MnIow8d22qPo2rVm5DJIyJOo/0o0Q== X-Received: by 2002:a05:6a21:9812:b0:a3:7d0b:5dcb with SMTP id ue18-20020a056a21981200b000a37d0b5dcbmr767910pzb.15.1675924233467; Wed, 08 Feb 2023 22:30:33 -0800 (PST) Received: from debug.ba.rivosinc.com ([66.220.2.162]) by smtp.gmail.com with ESMTPSA id u15-20020aa7848f000000b00593c434b1b8sm543649pfn.48.2023.02.08.22.30.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 08 Feb 2023 22:30:32 -0800 (PST) From: Deepak Gupta To: qemu-devel@nongnu.org, Palmer Dabbelt , Alistair Francis Cc: Deepak Gupta , Kip Walker , qemu-riscv@nongnu.org Subject: [PATCH v1 RFC Zisslpcfi 9/9] target/riscv: diassembly support for zisslpcfi instructions Date: Wed, 8 Feb 2023 22:29:47 -0800 Message-Id: <20230209062947.3585481-10-debug@rivosinc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230209062947.3585481-1-debug@rivosinc.com> References: <20230209062947.3585481-1-debug@rivosinc.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::635; envelope-from=debug@rivosinc.com; helo=mail-pl1-x635.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 autolearn=unavailable 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+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org This patch adds support to disassemble Zisslpcfi instructions. Signed-off-by: Deepak Gupta Signed-off-by: Kip Walker --- disas/riscv.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 126 insertions(+), 1 deletion(-) diff --git a/disas/riscv.c b/disas/riscv.c index d216b9c39b..d16ee617b0 100644 --- a/disas/riscv.c +++ b/disas/riscv.c @@ -163,6 +163,7 @@ typedef enum { rv_codec_v_i, rv_codec_vsetvli, rv_codec_vsetivli, + rv_codec_lp, } rv_codec; typedef enum { @@ -935,6 +936,19 @@ typedef enum { rv_op_vsetvli = 766, rv_op_vsetivli = 767, rv_op_vsetvl = 768, + rv_op_lpsll = 769, + rv_op_lpcll = 770, + rv_op_lpsml = 771, + rv_op_lpcml = 772, + rv_op_lpsul = 773, + rv_op_lpcul = 774, + rv_op_sspush = 775, + rv_op_sspop = 776, + rv_op_ssprr = 777, + rv_op_ssamoswap = 778, + rv_op_sschkra = 779, + rv_op_zimops_r = 780, + rv_op_zimops_rr = 781, } rv_op; /* structures */ @@ -1011,6 +1025,7 @@ static const char rv_vreg_name_sym[32][4] = { #define rv_fmt_pred_succ "O\tp,s" #define rv_fmt_rs1_rs2 "O\t1,2" #define rv_fmt_rd_imm "O\t0,i" +#define rv_fmt_imm "O\ti" #define rv_fmt_rd_offset "O\t0,o" #define rv_fmt_rd_rs1_rs2 "O\t0,1,2" #define rv_fmt_frd_rs1 "O\t3,1" @@ -2065,7 +2080,20 @@ const rv_opcode_data opcode_data[] = { { "vsext.vf8", rv_codec_v_r, rv_fmt_vd_vs2_vm, NULL, rv_op_vsext_vf8, rv_op_vsext_vf8, 0 }, { "vsetvli", rv_codec_vsetvli, rv_fmt_vsetvli, NULL, rv_op_vsetvli, rv_op_vsetvli, 0 }, { "vsetivli", rv_codec_vsetivli, rv_fmt_vsetivli, NULL, rv_op_vsetivli, rv_op_vsetivli, 0 }, - { "vsetvl", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, rv_op_vsetvl, rv_op_vsetvl, 0 } + { "vsetvl", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, rv_op_vsetvl, rv_op_vsetvl, 0 }, + { "lpsll", rv_codec_lp, rv_fmt_imm, NULL, 0, 0, 0 }, + { "lpcll", rv_codec_lp, rv_fmt_imm, NULL, 0, 0, 0 }, + { "lpsml", rv_codec_lp, rv_fmt_imm, NULL, 0, 0, 0 }, + { "lpcml", rv_codec_lp, rv_fmt_imm, NULL, 0, 0, 0 }, + { "lpsul", rv_codec_lp, rv_fmt_imm, NULL, 0, 0, 0 }, + { "lpcul", rv_codec_lp, rv_fmt_imm, NULL, 0, 0, 0 }, + { "sspush", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 }, + { "sspop", rv_codec_r, rv_fmt_rd, NULL, 0, 0, 0 }, + { "ssprr", rv_codec_r, rv_fmt_rd, NULL, 0, 0, 0 }, + { "ssamoswap", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, + { "sschkra", rv_codec_none, rv_fmt_none, NULL, 0, 0, 0 }, + { "zimops_r", rv_codec_r, rv_fmt_rd, NULL, 0, 0, 0 }, + { "zimops_rr", rv_codec_r, rv_fmt_rd, NULL, 0, 0, 0 } }; /* CSR names */ @@ -2084,6 +2112,8 @@ static const char *csr_name(int csrno) case 0x000a: return "vxrm"; case 0x000f: return "vcsr"; case 0x0015: return "seed"; + case 0x0006: return "lplr"; + case 0x0020: return "ssp"; case 0x0040: return "uscratch"; case 0x0041: return "uepc"; case 0x0042: return "ucause"; @@ -3554,6 +3584,87 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) case 1: op = rv_op_csrrw; break; case 2: op = rv_op_csrrs; break; case 3: op = rv_op_csrrc; break; + case 4: + /* if matches mop_r mask */ + if ((((inst >> 15) & 0b10110011110000000) == + 0b10000001110000000)) { + if ((inst >> 25) == 0b1000000) { + switch ((inst >> 20) & 0b11) { + case 0: /* sspush and sspop */ + if (((inst >> 15) & 0b11111) && + !((inst >> 7) & 0b11111)) + op = rv_op_sspush; + if (!((inst >> 15) & 0b11111) && + ((inst >> 7) & 0b11111)) + op = rv_op_sspop; + break; + + case 1: /* ssprr */ + if (!((inst >> 15) & 0b11111) && + ((inst >> 7) & 0b11111)) + op = rv_op_ssprr; + break; + + default: + op = rv_op_zimops_r; + break; + } + } else { + op = rv_op_zimops_r; + } + } else if (((inst >> 15) & 0b10110010000000000) == + 0b10000010000000000) { /* if matches mop_rr mask */ + switch (inst >> 28) { + case 0b1000: + switch ((inst >> 7) & 0b11111) { + case 0b00000: + /* collect 5 bits */ + switch (((inst >> 23) & 0b11111)) { + case 23: + op = rv_op_lpcul; + break; + case 22: + op = rv_op_lpsul; + break; + case 13: + op = rv_op_lpcml; + break; + case 12: + op = rv_op_lpsml; + break; + case 6: + case 7: + op = rv_op_lpcll; + break; + case 4: + case 5: + op = rv_op_lpsll; + break; + default: + if (inst == + 0b10001010000100101100000001110011) { + op = rv_op_sschkra; + } else { + op = rv_op_zimops_rr; + } + break; + } + break; + default: + if ((inst >> 26) == 0b100000) { + op = rv_op_ssamoswap; + } else { + op = rv_op_zimops_rr; + } + break; + } + break; + default: + op = rv_op_zimops_rr; + break; + } + } + break; case 5: op = rv_op_csrrwi; break; case 6: op = rv_op_csrrsi; break; case 7: op = rv_op_csrrci; break; @@ -3883,6 +3994,17 @@ static uint32_t operand_vm(rv_inst inst) return (inst << 38) >> 63; } +static uint32_t operand_lpl(rv_inst inst) +{ + uint32_t label_width = 9; + + if ((inst >> 26) & 0b11) { + label_width = 8; + } + + return (inst >> 15) & ((1 << label_width) - 1); +} + /* decode operands */ static void decode_inst_operands(rv_decode *dec, rv_isa isa) @@ -4199,6 +4321,9 @@ static void decode_inst_operands(rv_decode *dec, rv_isa isa) dec->imm = operand_vimm(inst); dec->vzimm = operand_vzimm10(inst); break; + case rv_codec_lp: + dec->imm = operand_lpl(inst); + break; }; }