From patchwork Mon Mar 5 16:03:42 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 130651 Delivered-To: patch@linaro.org Received: by 10.46.66.2 with SMTP id p2csp2853455lja; Mon, 5 Mar 2018 08:06:54 -0800 (PST) X-Google-Smtp-Source: AG47ELtjohtkEa9UXP39UPMRwIRyu3QXmkl+FMtsPz6eY4//N3g27+Lg2HAqgFX8ARtIH4TS1698 X-Received: by 10.107.9.138 with SMTP id 10mr17583423ioj.257.1520266014662; Mon, 05 Mar 2018 08:06:54 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520266014; cv=none; d=google.com; s=arc-20160816; b=hZ5JdqPWQYUubWs7mhEwm+H0QCLi/CVkgQbSSjqUddzGOSOzRf6E5WJNYpVIxeSdoP 1fu4VTV5xf34nkqptpWd2hqc0qheiPMN4nbysUzJNB0Oq7QhYrQIpKNlT8DCcUs9MLf/ Qj1Egf3/2IS8BWpLkPuX0gcuCGStLhBS6gkdCKyLsgOJxJ4bCZnnNllZanh/Q3lq6PlA ctTdxfFUzg9K7Oo/i5JSR1qTbZDx15WhEWOLCSxtd3Ra7Xqn6pXybABN9t4Q8Stn6xyU 5wzAr1z/QuDs9kcoxUY5MNjCa9mddPXRUxGo63RE6+ccjP4xxkwW121ZZAe+3EOoM9qZ us+Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version :list-subscribe:list-help:list-post:list-unsubscribe:list-id :precedence:subject:cc:references:in-reply-to:message-id:date:to :from:dkim-signature:arc-authentication-results; bh=toM9FEbn6Fa3+YLTR64c3r2naw0Pprkeo5Kppxh88N4=; b=VT/9c29YkfcLmvUdDf7DNBoV6SBLA/Bw2IMrybf3Rt4ctqKzKi2coJs/8OzG42mwOX 2Aipyb4MxqGcT3StSwFVIaD6rChlh0ofjUnTrHRsbgDzLj0TLIhH0rBCTH8OXWNFl6O4 mHKhrDgUdIFl0mw/92JmyN+toUBkKBMcmNmz3zy4OPnvfmGSpNJuBFr0Kn9Tm9ioU3Ll lgdw3FPSEmgaxSpxlbXQ4I0CZPvic+fAuj9EdG4gXXGc7Jt3FPJjObAAbJFM4clF3kqr XGt0LvxhFafhrUb8ebAK6hKIcz6dibVF8PS1qZcE70D7k3RhrXWpnVg15V9nVXwybG7Y RMrg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=AVfi8TNz; spf=pass (google.com: best guess record for domain of xen-devel-bounces@lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org. [192.237.175.120]) by mx.google.com with ESMTPS id v2si6042840ita.52.2018.03.05.08.06.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 05 Mar 2018 08:06:54 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of xen-devel-bounces@lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=AVfi8TNz; spf=pass (google.com: best guess record for domain of xen-devel-bounces@lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1essbb-0007lF-He; Mon, 05 Mar 2018 16:04:51 +0000 Received: from us1-rack-dfw2.inumbo.com ([104.130.134.6]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1essbZ-0007hF-K0 for xen-devel@lists.xenproject.org; Mon, 05 Mar 2018 16:04:49 +0000 X-Inumbo-ID: c6271aeb-208e-11e8-ba59-bc764e045a96 Received: from mail-wm0-x22e.google.com (unknown [2a00:1450:400c:c09::22e]) by us1-rack-dfw2.inumbo.com (Halon) with ESMTPS id c6271aeb-208e-11e8-ba59-bc764e045a96; Mon, 05 Mar 2018 17:03:42 +0100 (CET) Received: by mail-wm0-x22e.google.com with SMTP id t3so16904584wmc.2 for ; Mon, 05 Mar 2018 08:04:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=3rYOLFTCMFJQX/QEz8+U5N8zCXtgZ71Bo0iyJXrmw0Q=; b=AVfi8TNzDtKJReBoNtUeVQQ6eAbLnnE3uk5iEfVlM21ziYp3L/BNFsG1/+lhn4PhD7 Smqc2cZNmRI3jckOYHBpJr+fRJuyVdW83AtMb1k1uefebBcEVDAtgLRrVnVR/uKSHJcc pmWmZ28Q6+vXXnLTPtccEeBGNBTYGJCpTh+jc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=3rYOLFTCMFJQX/QEz8+U5N8zCXtgZ71Bo0iyJXrmw0Q=; b=YDk0I9Q7dUlzV+Be+mTKXAS4EO5vO4NKTVA0uxzNGbmpPt7ih2lXLZ9EqQ4Hd819vp GIanTfBqr6g6+PSHKEWSRfHTxnUEsn99QjHHbD3bGqCJVbmEvWIuNlwBmHe/+u1h9GGz GTIIgQm6OOKQ2kRZ1YPkol1CIfgvKHHpdNXkJYYsy4UuCLF4I01YiHrsC4s/aIuZXd6Z SjqZ0WQOVYaiKK4g+dzEUqwdiDn9aIzGsg5L9DnYWwtP04NOcJHTY6ytxO6Yyxqv4ZX/ OecXT5m1Bm4zgUXkPlXlL2hu7yPPeuQY+CGxxSahdfr7qMNsL233BHJUhWaSZGa0UXFc HD9g== X-Gm-Message-State: AElRT7FzyDTXyq5xWr0VE5hBf9RD4vUQOxQIqJVSbGVbuMGLlGuvwuXr ymoj7qUaJZ/tjgZpNVQicOpMQQ== X-Received: by 10.28.108.7 with SMTP id h7mr8060309wmc.35.1520265886762; Mon, 05 Mar 2018 08:04:46 -0800 (PST) Received: from e104803-lin.lan (mail.andrep.de. [217.160.17.100]) by smtp.gmail.com with ESMTPSA id y6sm6574381wmy.14.2018.03.05.08.04.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 05 Mar 2018 08:04:46 -0800 (PST) From: Andre Przywara To: Julien Grall , Stefano Stabellini Date: Mon, 5 Mar 2018 16:03:42 +0000 Message-Id: <20180305160415.16760-25-andre.przywara@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180305160415.16760-1-andre.przywara@linaro.org> References: <20180305160415.16760-1-andre.przywara@linaro.org> Cc: xen-devel@lists.xenproject.org Subject: [Xen-devel] [PATCH 24/57] ARM: timer: Handle level triggered IRQs correctly X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" The ARM Generic Timer uses a level-sensitive interrupt semantic. We easily catch when the line goes high, as this triggers the hardware IRQ. However we have to sync the state of the interrupt condition at certain points to catch when the line goes low and we can remove the vtimer vIRQ from the vGIC (and the LR). The VGIC in Xen so far only implemented edge triggered vIRQs, really, so we need to add new functionality to re-sample the interrupt state. Signed-off-by: Andre Przywara --- Changelog RFC ... v1: - extend comments - don't read CNTV_CVAL_EL0 - use symbolic names for constants xen/arch/arm/time.c | 36 ++++++++++++++++++++++++++++++++++++ xen/arch/arm/traps.c | 6 ++++++ xen/include/xen/timer.h | 2 ++ 3 files changed, 44 insertions(+) diff --git a/xen/arch/arm/time.c b/xen/arch/arm/time.c index c11fcfeadd..c0ae781ecd 100644 --- a/xen/arch/arm/time.c +++ b/xen/arch/arm/time.c @@ -263,6 +263,42 @@ static void vtimer_interrupt(int irq, void *dev_id, struct cpu_user_regs *regs) vgic_inject_irq(current->domain, current, current->arch.virt_timer.irq, true); } +/** + * vtimer_sync() - update the state of the virtual timer after a guest run + * @vcpu: The VCPU to sync the arch timer state + * + * After returning from a guest, update the state of the virtual interrupt + * line, to model the level triggered interrupt correctly. + * If the guest has handled a timer interrupt, the virtual interrupt line + * needs to be lowered explicitly. vgic_inject_irq() takes care of that. + */ +void vtimer_sync(struct vcpu *vcpu) +{ + struct vtimer *vtimer = &vcpu->arch.virt_timer; + uint32_t vtimer_ctl = READ_SYSREG32(CNTV_CTL_EL0); + bool level; + + /* + * Technically the mask should include the CNTx_CTL_MASK bit here, + * to catch if the timer interrupt is masked. However Xen always masks + * the timer upon entering the hypervisor, leaving it up to the guest + * to un-mask it. So we would always read a "low" level, despite the + * condition being actually "high". + * Ignoring the mask bit solves this (for now). + * Another possible check would be to compare the value of CNTVCT_EL0 + * against vtimer->cval and derive the interrupt state from that. + */ + vtimer_ctl &= (CNTx_CTL_ENABLE | CNTx_CTL_PENDING); + level = (vtimer_ctl == (CNTx_CTL_ENABLE | CNTx_CTL_PENDING)); + + /* + * TODO: The proper fix for this is to make vtimer vIRQ hardware mapped, + * but this requires reworking the arch timer to implement this. + */ + + vgic_inject_irq(vcpu->domain, vcpu, vtimer->irq, level); +} + /* * Arch timer interrupt really ought to be level triggered, since the * design of the timer/comparator mechanism is based around that diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c index 7411bff7a7..0713723bb7 100644 --- a/xen/arch/arm/traps.c +++ b/xen/arch/arm/traps.c @@ -2024,6 +2024,12 @@ static void enter_hypervisor_head(struct cpu_user_regs *regs) if ( current->arch.hcr_el2 & HCR_VA ) current->arch.hcr_el2 = READ_SYSREG(HCR_EL2); + /* + * We need to update the state of our emulated devices using level + * triggered interrupts before syncing back the VGIC state. + */ + vtimer_sync(current); + vgic_sync_from_lrs(current); } } diff --git a/xen/include/xen/timer.h b/xen/include/xen/timer.h index 4513260b0d..eddbbf3903 100644 --- a/xen/include/xen/timer.h +++ b/xen/include/xen/timer.h @@ -94,6 +94,8 @@ DECLARE_PER_CPU(s_time_t, timer_deadline); /* Arch-defined function to reprogram timer hardware for new deadline. */ int reprogram_timer(s_time_t timeout); +void vtimer_sync(struct vcpu *vcpu); + /* Calculate the aligned first tick time for a given periodic timer. */ s_time_t align_timer(s_time_t firsttick, uint64_t period);