From nobody Mon Apr 29 05:06:43 2024 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; 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=fail(p=none dis=none) header.from=arm.com Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1657096003759621.2604654183518; Wed, 6 Jul 2022 01:26:43 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.361955.591747 (Exim 4.92) (envelope-from ) id 1o90MW-0003zQ-T6; Wed, 06 Jul 2022 08:26:20 +0000 Received: by outflank-mailman (output) from mailman id 361955.591747; Wed, 06 Jul 2022 08:26:20 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1o90MW-0003zJ-Q3; Wed, 06 Jul 2022 08:26:20 +0000 Received: by outflank-mailman (input) for mailman id 361955; Wed, 06 Jul 2022 08:26:19 +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 1o90MV-0003zD-IM for xen-devel@lists.xenproject.org; Wed, 06 Jul 2022 08:26:19 +0000 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by se1-gles-sth1.inumbo.com (Halon) with ESMTP id 4eb6bb86-fd05-11ec-bd2d-47488cf2e6aa; Wed, 06 Jul 2022 10:26:18 +0200 (CEST) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id D900B1596; Wed, 6 Jul 2022 01:26:17 -0700 (PDT) Received: from a015971.shanghai.arm.com (unknown [10.169.188.104]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 2D9923F792; Wed, 6 Jul 2022 01:26:14 -0700 (PDT) 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: 4eb6bb86-fd05-11ec-bd2d-47488cf2e6aa From: Jiamei Xie To: xen-devel@lists.xenproject.org Cc: Jiamei Xie , Stefano Stabellini , Julien Grall , Bertrand Marquis , Volodymyr Babchuk , Wei Chen Subject: [PATCH v4] xen/arm: avoid overflow when setting vtimer in context switch Date: Wed, 6 Jul 2022 16:25:58 +0800 Message-Id: <20220706082558.1116811-1-jiamei.xie@arm.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1657096005934100001 Content-Type: text/plain; charset="utf-8" virt_vtimer_save() will calculate the next deadline when the vCPU is scheduled out. At the moment, Xen will use the following equation: virt_timer.cval + virt_time_base.offset - boot_count The three values are 64-bit and one (cval) is controlled by domain. In theory, it would be possible that the domain has started a long time after the system boot. So virt_time_base.offset - boot_count may be a large numbers. This means a domain may inadvertently set a cval so the result would overflow. Consequently, the deadline would be set very far in the future. This could result to loss of timer interrupts or the vCPU getting block "forever". One way to solve the problem, would be to separately 1) compute when the domain was created in ns 2) convert cval to ns 3) Add 1 and 2 together The first part of the equation never change (the value is set/known at domain creation). So take the opportunity to store it in domain structure. Signed-off-by: Jiamei Xie Reviewed-by: Bertrand Marquis Reviewed-by: Julien Grall --- was "xen/arm: avoid vtimer flip-flop transition in context switch". v4 changes: - re-write commit message --- v3 changes: - re-write commit message - store nanoseconds in virt_timer_base instead of adding a new structure - assign to nanoseconds first, then seconds --- xen/arch/arm/include/asm/domain.h | 1 + xen/arch/arm/vtimer.c | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/xen/arch/arm/include/asm/domain.h b/xen/arch/arm/include/asm/d= omain.h index ed63c2b6f9..cd9ce19b4b 100644 --- a/xen/arch/arm/include/asm/domain.h +++ b/xen/arch/arm/include/asm/domain.h @@ -71,6 +71,7 @@ struct arch_domain =20 struct { uint64_t offset; + s_time_t nanoseconds; } virt_timer_base; =20 struct vgic_dist vgic; diff --git a/xen/arch/arm/vtimer.c b/xen/arch/arm/vtimer.c index 6b78fea77d..aeaea78e4c 100644 --- a/xen/arch/arm/vtimer.c +++ b/xen/arch/arm/vtimer.c @@ -63,7 +63,9 @@ static void virt_timer_expired(void *data) int domain_vtimer_init(struct domain *d, struct xen_arch_domainconfig *con= fig) { d->arch.virt_timer_base.offset =3D get_cycles(); - d->time_offset.seconds =3D ticks_to_ns(d->arch.virt_timer_base.offset = - boot_count); + d->arch.virt_timer_base.nanoseconds =3D + ticks_to_ns(d->arch.virt_timer_base.offset - boot_count); + d->time_offset.seconds =3D d->arch.virt_timer_base.nanoseconds; do_div(d->time_offset.seconds, 1000000000); =20 config->clock_frequency =3D timer_dt_clock_frequency; @@ -144,8 +146,9 @@ void virt_timer_save(struct vcpu *v) if ( (v->arch.virt_timer.ctl & CNTx_CTL_ENABLE) && !(v->arch.virt_timer.ctl & CNTx_CTL_MASK)) { - set_timer(&v->arch.virt_timer.timer, ticks_to_ns(v->arch.virt_time= r.cval + - v->domain->arch.virt_timer_base.offset - boot_count)); + set_timer(&v->arch.virt_timer.timer, + v->domain->arch.virt_timer_base.nanoseconds + + ticks_to_ns(v->arch.virt_timer.cval)); } } =20 --=20 2.25.1