From nobody Mon Jan 26 09:20:21 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1769100493; cv=none; d=zohomail.com; s=zohoarc; b=INBiK349YeK9cTHpJ6aHc/gK/UiUIH5jiI5qg6i1Qn2VpeZ9bT2HlsRcEdLceBvn/Zjp5Fkn083vGPdY5Hw0wzm6JZFaVe0VEh+/JWar+WCnKEPH4VlsGCWmEjuLdPv82ivA2hOXW/wK0xqd7QXfQt6jgP+fiC6GIUuO2oPBHjo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1769100493; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=6yeF8Jc7Y0UzeLgMob1T0cLJ1Uc8AiT2zOW9g8mOyGs=; b=NKxlpvW2gqIq4wQSA46arLjIt4OTfC1LAfTwT4FVB/2a11fAP82ynxx5crkNXmXcEVo1D1JBkn2gervkXsb4m0R51uGhn6QbwvPkrclPuAOjtqCvJKJ+JlivJmU3mHSfEp9uLAS3CE0wEFi13TTx+2gKCSlLBdBXqMXHfx9EMR0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1769100493406136.36756746063827; Thu, 22 Jan 2026 08:48:13 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1211345.1522886 (Exim 4.92) (envelope-from ) id 1vixqV-0007WK-3Q; Thu, 22 Jan 2026 16:47:47 +0000 Received: by outflank-mailman (output) from mailman id 1211345.1522886; Thu, 22 Jan 2026 16:47:47 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vixqU-0007W9-Vv; Thu, 22 Jan 2026 16:47:46 +0000 Received: by outflank-mailman (input) for mailman id 1211345; Thu, 22 Jan 2026 16:47:45 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vixqT-0007Id-Ct for xen-devel@lists.xenproject.org; Thu, 22 Jan 2026 16:47:45 +0000 Received: from mail-ed1-x52d.google.com (mail-ed1-x52d.google.com [2a00:1450:4864:20::52d]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 12e17298-f7b2-11f0-b15e-2bf370ae4941; Thu, 22 Jan 2026 17:47:44 +0100 (CET) Received: by mail-ed1-x52d.google.com with SMTP id 4fb4d7f45d1cf-6505d3b84bcso1589974a12.3 for ; Thu, 22 Jan 2026 08:47:44 -0800 (PST) Received: from fedora (user-109-243-67-101.play-internet.pl. [109.243.67.101]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-b879513e951sm1686014966b.7.2026.01.22.08.47.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Jan 2026 08:47:42 -0800 (PST) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 12e17298-f7b2-11f0-b15e-2bf370ae4941 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1769100463; x=1769705263; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=6yeF8Jc7Y0UzeLgMob1T0cLJ1Uc8AiT2zOW9g8mOyGs=; b=dzhzdsGsNLUKHpBU1UeScuv5wScuBRKU41tApu0ec6Ko407QhGrku7BMwOcOTMVW82 mou3M9EPJIJchXivtYowS/iQA0+2HlsJ2JnNlfwEpPybLDHJimQy35bNdcVwCBBqiI+y lfEm7oonjgtr+cF96EG5QAR1KJlSAo9dcFyBpH2347BKpJuSv4UUGUOg7oFwFRB1jOYd b3U9XSuTCsXKfc7sgq3jUVDFGE2UNAjysRFU4m/na5rLyL8Fs7/ArE9OoeKEwTmmozCu 1Tr4PSIaYVbeDQWGs1kCx1hUc4seq4hkiTBFtYUHwpFtRzO7nuf+D0otCDNwWUsytFrN VZeA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1769100463; x=1769705263; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=6yeF8Jc7Y0UzeLgMob1T0cLJ1Uc8AiT2zOW9g8mOyGs=; b=WY5fya9N7r/5XHy2AFxGHWjmncvj0nPZvhiqZL9HVjxHnQLof7k/2r53ZtnpQj9XOp 8GmPieC7dvMXkNqXDB/UM8fe2Kjzs6YxCrBNTTqsBjV9OJLJiPsxPChDSOFwibMrghFS 9Ki7wyimUpBdv1vvOJoBHWcIJ/CEArtsoWURWKGcrUYywhocSxXvlUrzLl7vedHlx/Hr xX4OWcY9WeOnBbpx78bxYvJgleydJFRLT/naZrKWKDjsh96RWMeplOMZc3tZvajQtkVW 3e3LrA4nXh8vw9BMm5O8jPntFmBbRK4Zi8yI+fRGbShLoPmsspKFlYS1qNgJ6Tg49jV+ svlA== X-Gm-Message-State: AOJu0YzYDl3k7LDpSrPNcGSF23TMZzKJOWknRlbJGlPWcK51wMfMsSXa LojmIOdLGNIqwjsEoDsdDr7FQAy+DSr+kWrtNz4cX5xQFBSSPQIn7lY4tuSTvA== X-Gm-Gg: AZuq6aJsIpbUBvfNeU0MUKKCtKBd093hpPJdUJCrL/zbpiGQZ/J0lLpgSDwbERmVXns sJkwO9UjWzY0vzh5ozRo5hkA3p+DmgNRwCws1RYUgSkUwcAec7sn15ULbr6/u5t8Q1dgYTHc0bj XdckiET5x34xgu8Jz8n3s9yBmTwIfUPyUpRxweftoAaYm7PvTLG/AI8ZCJ5LdJheGdWFQufDaAV eyOU2C1eMSYqK6k8ibYuzXZv2FvCeI1CgU0sfIUs/m7pustwOymx4mHClKPOXWAhtERawDGABTr 5ZGfQtBXwb+d1m8MntvQL8nnahpnoTx4Hv3ujCY+T1MAoumwQjTu825i+s5beOSXfn88CLESk/t GXUJmQoaRNSAf4ipJZemOUDPVF5rb3ucBS/Q+nSFQSBFjn1V6N/IyKiSJRCG5CcFFdpkGq9T0AZ RCXYz3Ve0Genk2iLW8eQnkSIe86BVDSCG8YYC0lSJ4+ptVypq4uEZ1Xw== X-Received: by 2002:a17:907:1ca9:b0:b87:35fc:ae5f with SMTP id a640c23a62f3a-b87930381c7mr2000586266b.52.1769100463285; Thu, 22 Jan 2026 08:47:43 -0800 (PST) From: Oleksii Kurochko To: xen-devel@lists.xenproject.org Cc: Oleksii Kurochko , Alistair Francis , Connor Davis , Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , Julien Grall , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Stefano Stabellini , Romain Caritey Subject: [PATCH v2 03/16] xen/riscv: implement vcpu_csr_init() Date: Thu, 22 Jan 2026 17:47:18 +0100 Message-ID: <57ef3bcff854d4b50641641d300b3e8aa715c3c3.1769099885.git.oleksii.kurochko@gmail.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1769100495532154100 Content-Type: text/plain; charset="utf-8" Introduce vcpu_csr_init() to set up the initial hypervisor-visible CSR state for a vCPU before it is first scheduled. The function configures trap and interrupt delegation to VS-mode by setting the appropriate bits in the hedeleg and hideleg registers, initializes hstatus so that execution enters VS-mode when control is passed to the guest, and restricts guest access to hardware performance counters by initializing hcounteren, as unrestricted access would require additional handling in Xen. When the Smstateen and SSAIA extensions are available, access to AIA CSRs and IMSIC guest interrupt files is enabled by setting the corresponding bits in hstateen0, avoiding unnecessary traps into Xen (note that SVSLCT(Supervisor Virtual Select) name is used intead of CSRIND as OpenSBI uses such name and riscv_encoding.h is mostly based on it). If the Svpbmt extension is supported, the PBMTE bit is set in henvcfg to allow its use for VS-stage address translation. Guest access to the ENVCFG CSR is also enabled by setting ENVCFG bit in hstateen0, as a guest may need to control certain characteristics of the U-mode (VU-mode when V=3D1) execution environment. For CSRs that may contain read-only bits (e.g. hedeleg, hideleg, hstateen0), the written value is re-read from hardware and cached in vcpu->arch to avoid divergence between the software state and the actual CSR contents. As hstatus is not part of struct arch_vcpu (it already resides in struct cpu_user_regs), introduce vcpu_guest_cpu_user_regs() to provide a uniform way to access hstatus and other guest CPU user registers. This establishes a consistent and well-defined initial CSR state for vCPUs prior to their first context switch. Signed-off-by: Oleksii Kurochko --- Changes in v2: - As hstatus isn't a part of arch_vcpu structure (as it is already a part = of cpu_user_regs) introduce vcpu_guest_cpu_user_regs() to be able to access hstatus and other CPU user regs. - Sort hideleg bit setting by value. Drop a stray blank. - Drop | when the first initialization of hcounteren and hennvcfg happen. - Introduce HEDELEG_DEFAULT. Sort set bits by value and use BIT() macros instead of open-coding it. - Apply pattern csr_write() -> csr_read() for hedeleg and hideleg instead of direct bit setting in v->arch.h{i,e}deleg as it could be that for some reason some bits of hedeleg and hideleg are r/o. The similar patter is used for hstateen0 as some of the bits could be r/= o. - Add check that SSAIA is avaialable before setting of SMSTATEEN0_AIA | SMSTATEEN0_IMSIC | SMSTATEEN0_SVSLCT bits. - Drop local variables hstatus, hideleg and hedeleg as they aren't used anymore. --- xen/arch/riscv/cpufeature.c | 1 + xen/arch/riscv/domain.c | 73 +++++++++++++++++++++ xen/arch/riscv/include/asm/cpufeature.h | 1 + xen/arch/riscv/include/asm/current.h | 2 + xen/arch/riscv/include/asm/riscv_encoding.h | 2 + 5 files changed, 79 insertions(+) diff --git a/xen/arch/riscv/cpufeature.c b/xen/arch/riscv/cpufeature.c index 02b68aeaa49f..03e27b037be0 100644 --- a/xen/arch/riscv/cpufeature.c +++ b/xen/arch/riscv/cpufeature.c @@ -137,6 +137,7 @@ const struct riscv_isa_ext_data __initconst riscv_isa_e= xt[] =3D { RISCV_ISA_EXT_DATA(zbb), RISCV_ISA_EXT_DATA(zbs), RISCV_ISA_EXT_DATA(smaia), + RISCV_ISA_EXT_DATA(smstateen), RISCV_ISA_EXT_DATA(ssaia), RISCV_ISA_EXT_DATA(svade), RISCV_ISA_EXT_DATA(svpbmt), diff --git a/xen/arch/riscv/domain.c b/xen/arch/riscv/domain.c index 9c546267881b..3ae5fa3a8805 100644 --- a/xen/arch/riscv/domain.c +++ b/xen/arch/riscv/domain.c @@ -5,6 +5,77 @@ #include #include =20 +#include +#include +#include + +#define HEDELEG_DEFAULT (BIT(CAUSE_MISALIGNED_FETCH, U) | \ + BIT(CAUSE_FETCH_ACCESS, U) | \ + BIT(CAUSE_ILLEGAL_INSTRUCTION, U) | \ + BIT(CAUSE_BREAKPOINT, U) | \ + BIT(CAUSE_MISALIGNED_LOAD, U) | \ + BIT(CAUSE_LOAD_ACCESS, U) | \ + BIT(CAUSE_MISALIGNED_STORE, U) | \ + BIT(CAUSE_STORE_ACCESS, U) | \ + BIT(CAUSE_USER_ECALL, U) | \ + BIT(CAUSE_FETCH_PAGE_FAULT, U) | \ + BIT(CAUSE_LOAD_PAGE_FAULT, U) | \ + BIT(CAUSE_STORE_PAGE_FAULT, U)) + +#define HIDELEG_DEFAULT (MIP_VSSIP | MIP_VSTIP | MIP_VSEIP) + +static void vcpu_csr_init(struct vcpu *v) +{ + register_t hstateen0; + + csr_write(CSR_HEDELEG, HEDELEG_DEFAULT); + v->arch.hedeleg =3D csr_read(CSR_HEDELEG); + + vcpu_guest_cpu_user_regs(v)->hstatus =3D HSTATUS_SPV | HSTATUS_SPVP; + + csr_write(CSR_HIDELEG, HIDELEG_DEFAULT); + v->arch.hideleg =3D csr_read(CSR_HIDELEG); + + /* + * VS should access only the time counter directly. + * Everything else should trap. + */ + v->arch.hcounteren =3D HCOUNTEREN_TM; + + if ( riscv_isa_extension_available(NULL, RISCV_ISA_EXT_svpbmt) ) + { + csr_write(CSR_HENVCFG, ENVCFG_PBMTE); + v->arch.henvcfg =3D csr_read(CSR_HENVCFG); + } + + if ( riscv_isa_extension_available(NULL, RISCV_ISA_EXT_smstateen) ) + { + if (riscv_isa_extension_available(NULL, RISCV_ISA_EXT_ssaia)) + /* + * If the hypervisor extension is implemented, the same three + * bitsare defined also in hypervisor CSR hstateen0 but concern + * only the state potentially accessible to a virtual machine + * executing in privilege modes VS and VU: + * bit 60 CSRs siselect and sireg (really vsiselect and + * vsireg) + * bit 59 CSRs siph and sieh (RV32 only) and stopi (really + * vsiph, vsieh, and vstopi) + * bit 58 all state of IMSIC guest interrupt files, inclu= ding + * CSR stopei (really vstopei) + * If one of these bits is zero in hstateen0, and the same bit= is + * one in mstateen0, then an attempt to access the correspondi= ng + * state from VS or VU-mode raises a virtual instruction excep= tion. + */ + hstateen0 =3D SMSTATEEN0_AIA | SMSTATEEN0_IMSIC | SMSTATEEN0_S= VSLCT; + + /* Allow guest to access CSR_ENVCFG */ + hstateen0 |=3D SMSTATEEN0_HSENVCFG; + + csr_write(CSR_HSTATEEN0, hstateen0); + v->arch.hstateen0 =3D csr_read(CSR_HSTATEEN0); + } +} + static void continue_new_vcpu(struct vcpu *prev) { BUG_ON("unimplemented\n"); @@ -33,6 +104,8 @@ int arch_vcpu_create(struct vcpu *v) v->arch.xen_saved_context.sp =3D (register_t)v->arch.cpu_info; v->arch.xen_saved_context.ra =3D (register_t)continue_new_vcpu; =20 + vcpu_csr_init(v); + /* Idle VCPUs don't need the rest of this setup */ if ( is_idle_vcpu(v) ) return rc; diff --git a/xen/arch/riscv/include/asm/cpufeature.h b/xen/arch/riscv/inclu= de/asm/cpufeature.h index b69616038888..ef02a3e26d2c 100644 --- a/xen/arch/riscv/include/asm/cpufeature.h +++ b/xen/arch/riscv/include/asm/cpufeature.h @@ -36,6 +36,7 @@ enum riscv_isa_ext_id { RISCV_ISA_EXT_zbb, RISCV_ISA_EXT_zbs, RISCV_ISA_EXT_smaia, + RISCV_ISA_EXT_smstateen, RISCV_ISA_EXT_ssaia, RISCV_ISA_EXT_svade, RISCV_ISA_EXT_svpbmt, diff --git a/xen/arch/riscv/include/asm/current.h b/xen/arch/riscv/include/= asm/current.h index 58c9f1506b7c..5fbee8182caa 100644 --- a/xen/arch/riscv/include/asm/current.h +++ b/xen/arch/riscv/include/asm/current.h @@ -48,6 +48,8 @@ DECLARE_PER_CPU(struct vcpu *, curr_vcpu); #define get_cpu_current(cpu) per_cpu(curr_vcpu, cpu) =20 #define guest_cpu_user_regs() ({ BUG_ON("unimplemented"); NULL; }) +#define vcpu_guest_cpu_user_regs(vcpu) \ + (&(vcpu)->arch.cpu_info->guest_cpu_user_regs) =20 #define switch_stack_and_jump(stack, fn) do { \ asm volatile ( \ diff --git a/xen/arch/riscv/include/asm/riscv_encoding.h b/xen/arch/riscv/i= nclude/asm/riscv_encoding.h index 1f7e612366f8..dd15731a86fa 100644 --- a/xen/arch/riscv/include/asm/riscv_encoding.h +++ b/xen/arch/riscv/include/asm/riscv_encoding.h @@ -228,6 +228,8 @@ #define ENVCFG_CBIE_INV _UL(0x3) #define ENVCFG_FIOM _UL(0x1) =20 +#define HCOUNTEREN_TM BIT(1, U) + /* =3D=3D=3D=3D=3D User-level CSRs =3D=3D=3D=3D=3D */ =20 /* User Trap Setup (N-extension) */ --=20 2.52.0