From nobody Mon Apr 13 03:28:25 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; 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=1772814850; cv=none; d=zohomail.com; s=zohoarc; b=fTLsDlhni6+3AeMXD5QWYi6lU4y+5nQRHAOks7yYF2ZUfSc11anBuqDM/P/kRsjL7aizJUXYOWr+xTp48ZG/y3vRe7qi8cUmqByjMahsZr2h1bY3S73+K7gyg4SCPojSeVf5p8BTxSXmSkXKkTSW+q45PEF4S2ityiFBhowo5sE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772814850; h=Content-Type: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=PUa+J5dx/g0jfCQXCa5GsS6lcARiceV/jkoJtxvsNwc=; b=WURQ4wtDqwzX6Hvsv5Sso9Ddtx5Wao8RroW8AZu5KpJa0mIh86OJi1pJeFsqQvQMCrnbyC43v4M1Lq20UkrwmufpftJIlwLAG+IysJq+tO7cGoupFPOeMei5IaooQD5ZqTDMFLgJqDv+bakve8V6PuIe8qFzQ2rfvEYIJAcuzdA= 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 1772814850866392.6799309190943; Fri, 6 Mar 2026 08:34:10 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1247977.1546360 (Exim 4.92) (envelope-from ) id 1vyY7a-0004CT-3q; Fri, 06 Mar 2026 16:33:50 +0000 Received: by outflank-mailman (output) from mailman id 1247977.1546360; Fri, 06 Mar 2026 16:33:50 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vyY7Z-0004CF-U1; Fri, 06 Mar 2026 16:33:49 +0000 Received: by outflank-mailman (input) for mailman id 1247977; Fri, 06 Mar 2026 16:33:48 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vyY7Y-0003HN-7G for xen-devel@lists.xenproject.org; Fri, 06 Mar 2026 16:33:48 +0000 Received: from mail-wm1-x32f.google.com (mail-wm1-x32f.google.com [2a00:1450:4864:20::32f]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 3f2fad62-197a-11f1-9ccf-f158ae23cfc8; Fri, 06 Mar 2026 17:33:46 +0100 (CET) Received: by mail-wm1-x32f.google.com with SMTP id 5b1f17b1804b1-4836f363ad2so110250565e9.1 for ; Fri, 06 Mar 2026 08:33:46 -0800 (PST) Received: from fedora (user-109-243-67-101.play-internet.pl. [109.243.67.101]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-439dae57c05sm4406550f8f.39.2026.03.06.08.33.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 06 Mar 2026 08:33:44 -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: 3f2fad62-197a-11f1-9ccf-f158ae23cfc8 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1772814825; x=1773419625; 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=PUa+J5dx/g0jfCQXCa5GsS6lcARiceV/jkoJtxvsNwc=; b=FEJfwGK+82JNUSYtm7sbdmwEJsaLrGrJOldr4U9TjjZBc/IbW3KtDjxQdmaTA7KJU8 NzdwaWERTvYKWp8Y8eAFlTs2ZK/fSCI3mDDGkGfgMbuCNMnd4eiSWZxMP2Kb5yZmvNNV 8MPo89b5wZGYfl56oP0XFCTc3fDvgCEFtweCus5S1FQxkaYVtDQ8ZvG+/dQqeOU2ce1W 28LPfEU1bcmgANBQpcPSXdT412ZPs58huHRHSbHi4mSkdhhcx0uem20gerzf9U7JlGY8 I/7rrSbqlD755pWs+7iZHch5nGYR4xOap6tT8+JS7Us91ySAoR3a0WDe2rC2sYAR3zTG TNuQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772814825; x=1773419625; 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=PUa+J5dx/g0jfCQXCa5GsS6lcARiceV/jkoJtxvsNwc=; b=Z6QOPQMsGUQfwTFVfotGfBbvJa/maJEl9Iy483ktG69nHXb1BcFXbmdsW9dGOSxyaV En17BBoF4U8NWOSFLo896X0AIZjNXCELcNcwJSye/Tv8ugbrT3mfQUB3T5kSbSESx2d5 p5fw68fIX2pBkc/m5qiZrJMb+bDWkDJqopIiWHHDCZldrdX05hr266dxlq/lyc1A+qXh iejuX8BWDyClHdqwidf7mnjp5zZEGJBeOK7OTYWCKzI7C335uCDn/D6QmD4RZ1PNh12r 3fe/xo7HaljEX28wHFbmEkiki/6CUhzi9dn1FGXF0394fUKSDU9t6celYuo6fK4c3Ai7 lZmA== X-Gm-Message-State: AOJu0YzZ6utrY3IClM0nINhNUwwmw4n1NDo1MkerSQpfIgn3IqAOHiMs PhpobhyEGf82VNqG+sXmtJ5S2wk4zZp2BtryX1FbXTl7QvHjQ9QyE/ckChPjAg== X-Gm-Gg: ATEYQzxJdu0QCB87WX9mhan8E5/pgCcvpwVvZ7Zvj9NOvkSWvpIfoWZMat1FjotI5iw W3ohdYfbqb6mA5wluowndGS2AcPX1Bzz527a/XiJJIyjuBqaWeA8ooDUZFAfho+Niilgki31VEw SE2euwW2WdA7WGYWm/H5Y2Z680braq47VisRrW9s/S115mskbR2RfWGMwfvS5V3tMNY1hGSWvgO nBypHyVH8SR7fJ7CRPH+4885WXviRahEjpJJKGm/Q6YPctdTjaCapKIbe9+wLkkYJqf1td1ucxh BmHnb1TaV2+ghd0rYcGHbds1JE8/IxPDbyJGI7DVP5DO1uGUUST4oIHM/6ZufsJnu8S6kymtxJY ubfvV9+lTHRHl9yOn/tc6ugeEbL537EDVmjUuawCi4OmJ4Yii9m0/JZUlwTGrrcIGJ/zRTYmPnV JsPduwWpJgnub7LH1Ks8KmnX4FYrmeakbXXY2dmicm5HsWDVJj8kRt1LR3xbAGa6k8AxruGg== X-Received: by 2002:a05:600c:198f:b0:483:6ff1:18b with SMTP id 5b1f17b1804b1-485268bd6cbmr46440355e9.0.1772814825032; Fri, 06 Mar 2026 08:33:45 -0800 (PST) From: Oleksii Kurochko To: xen-devel@lists.xenproject.org Cc: Romain Caritey , 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 Subject: [PATCH v7 05/14] xen/riscv: introduce basic vtimer infrastructure for guests Date: Fri, 6 Mar 2026 17:33:22 +0100 Message-ID: <1a5fcf53fa4a3e935b1814c129aa131fe1068168.1772814110.git.oleksii.kurochko@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1772814853140158500 Lay the groundwork for guest timer support by introducing a per-vCPU virtual timer backed by Xen=E2=80=99s common timer infrastructure. The virtual timer is programmed in response to the guest SBI sbi_set_timer() call and injects a virtual supervisor timer interrupt into the vCPU when it expires. While a dedicated struct vtimer is not strictly required at present, it is expected to become necessary once SSTC support is introduced. In particular, it will need to carry additional state such as whether SSTC is enabled, the next compare value (e.g. for the VSTIMECMP CSR) to be saved and restored across context switches, and time delta state (e.g. HTIMEDELTA) required for use cases such as migration. Introducing struct vtimer now avoids a later refactoring. Signed-off-by: Oleksii Kurochko Acked-by: Jan Beulich --- Changes in v6-v7: - Nothing changed. Only rebase. --- Changes in v5: - Drop copyright line from asm/vtimer.h. - Add Acked-by: Jan Beulich . --- Changes in v4: - Add vcpu_timer_destroy() to void arch_vcpu_destroy(). --- Changes in v3: - use one container_of() to get vcpu instead of two container_of()s. --- Changes in v2: - Drop domain_vtimer_init() as it does nothing. - Drop "struct vcpu *v;" from struct vtimer as it could be taken from arch_vcpu using container_of(). - Drop vtimer_initialized, use t->status =3D=3D TIMER_STATUS_invalid instead to understand if timer was or wasn't initialized. - Drop inclusion of xen/domain.h as xen/sched.h already includes it. - s/ xen/time.h/ xen.timer.h in vtimer.c. - Drop ULL in if-conidtion in vtimer_set_timer() as with the cast it isn't necessary to have suffix ULL. - Add migrate timer to vtimer_set_timer() to be sure that vtimer will occur on pCPU it was ran, so the signalling to that vCPU will (commonly) be cheaper. - Check if the timeout has already expired and just inject the event in vtimer_vtimer_set_timer(). - Drop const for ticks argument of vtimer_set_timer(). - Merge two patches to one: - xen/riscv: introduce vtimer - xen/riscv: introduce vtimer_set_timer() and vtimer_expired() --- xen/arch/riscv/Makefile | 1 + xen/arch/riscv/domain.c | 10 +++- xen/arch/riscv/include/asm/domain.h | 3 ++ xen/arch/riscv/include/asm/vtimer.h | 17 +++++++ xen/arch/riscv/vtimer.c | 71 +++++++++++++++++++++++++++++ 5 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 xen/arch/riscv/include/asm/vtimer.h create mode 100644 xen/arch/riscv/vtimer.c diff --git a/xen/arch/riscv/Makefile b/xen/arch/riscv/Makefile index bc47e83b26d7..ffbd7062e214 100644 --- a/xen/arch/riscv/Makefile +++ b/xen/arch/riscv/Makefile @@ -22,6 +22,7 @@ obj-y +=3D traps.o obj-y +=3D vmid.o obj-y +=3D vm_event.o obj-y +=3D vsbi/ +obj-y +=3D vtimer.o =20 $(TARGET): $(TARGET)-syms $(OBJCOPY) -O binary -S $< $@ diff --git a/xen/arch/riscv/domain.c b/xen/arch/riscv/domain.c index f3e3ad149453..b59e026a9635 100644 --- a/xen/arch/riscv/domain.c +++ b/xen/arch/riscv/domain.c @@ -10,6 +10,7 @@ #include #include #include +#include =20 struct csr_masks { register_t hedeleg; @@ -148,11 +149,14 @@ int arch_vcpu_create(struct vcpu *v) =20 vcpu_csr_init(v); =20 + if ( (rc =3D vcpu_vtimer_init(v)) ) + goto fail; + /* - * As the vtimer and interrupt controller (IC) are not yet implemented, + * As interrupt controller (IC) is not yet implemented, * return an error. * - * TODO: Drop this once the vtimer and IC are implemented. + * TODO: Drop this once IC is implemented. */ rc =3D -EOPNOTSUPP; goto fail; @@ -166,6 +170,8 @@ int arch_vcpu_create(struct vcpu *v) =20 void arch_vcpu_destroy(struct vcpu *v) { + vcpu_timer_destroy(v); + vfree((void *)&v->arch.cpu_info[1] - STACK_SIZE); } =20 diff --git a/xen/arch/riscv/include/asm/domain.h b/xen/arch/riscv/include/a= sm/domain.h index 59d23e4f9247..6c48bf13111d 100644 --- a/xen/arch/riscv/include/asm/domain.h +++ b/xen/arch/riscv/include/asm/domain.h @@ -8,6 +8,7 @@ #include =20 #include +#include =20 struct vcpu_vmid { uint64_t generation; @@ -49,6 +50,8 @@ struct arch_vcpu { =20 struct cpu_info *cpu_info; =20 + struct vtimer vtimer; + register_t hcounteren; register_t hedeleg; register_t hideleg; diff --git a/xen/arch/riscv/include/asm/vtimer.h b/xen/arch/riscv/include/a= sm/vtimer.h new file mode 100644 index 000000000000..111863610a92 --- /dev/null +++ b/xen/arch/riscv/include/asm/vtimer.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef ASM__RISCV__VTIMER_H +#define ASM__RISCV__VTIMER_H + +#include + +struct vtimer { + struct timer timer; +}; + +int vcpu_vtimer_init(struct vcpu *v); +void vcpu_timer_destroy(struct vcpu *v); + +void vtimer_set_timer(struct vtimer *t, uint64_t ticks); + +#endif /* ASM__RISCV__VTIMER_H */ diff --git a/xen/arch/riscv/vtimer.c b/xen/arch/riscv/vtimer.c new file mode 100644 index 000000000000..32d142bcdfcd --- /dev/null +++ b/xen/arch/riscv/vtimer.c @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +#include + +static void vtimer_expired(void *data) +{ + struct vtimer *t =3D data; + struct vcpu *v =3D container_of(t, struct vcpu, arch.vtimer); + + vcpu_set_interrupt(v, IRQ_VS_TIMER); +} + +int vcpu_vtimer_init(struct vcpu *v) +{ + struct vtimer *t =3D &v->arch.vtimer; + + init_timer(&t->timer, vtimer_expired, t, v->processor); + + return 0; +} + +void vcpu_timer_destroy(struct vcpu *v) +{ + struct vtimer *t =3D &v->arch.vtimer; + + if ( t->timer.status =3D=3D TIMER_STATUS_invalid ) + return; + + kill_timer(&v->arch.vtimer.timer); +} + +void vtimer_set_timer(struct vtimer *t, const uint64_t ticks) +{ + struct vcpu *v =3D container_of(t, struct vcpu, arch.vtimer); + s_time_t expires =3D ticks_to_ns(ticks - boot_clock_cycles); + + vcpu_unset_interrupt(v, IRQ_VS_TIMER); + + /* + * According to the RISC-V sbi spec: + * If the supervisor wishes to clear the timer interrupt without + * scheduling the next timer event, it can either request a timer + * interrupt infinitely far into the future (i.e., (uint64_t)-1), + * or it can instead mask the timer interrupt by clearing sie.STIE C= SR + * bit. + */ + if ( ticks =3D=3D ((uint64_t)~0) ) + { + stop_timer(&t->timer); + + return; + } + + if ( expires < NOW() ) + { + /* + * Simplify the logic if the timeout has already expired and just + * inject the event. + */ + stop_timer(&t->timer); + vcpu_set_interrupt(v, IRQ_VS_TIMER); + + return; + } + + migrate_timer(&t->timer, smp_processor_id()); + set_timer(&t->timer, expires); +} --=20 2.53.0