From patchwork Tue Aug 8 13:33:00 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anthony PERARD X-Patchwork-Id: 9888247 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 62276601EB for ; Tue, 8 Aug 2017 13:35:12 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 544A62886F for ; Tue, 8 Aug 2017 13:35:12 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 492E8288BC; Tue, 8 Aug 2017 13:35:12 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id E2BFE2886F for ; Tue, 8 Aug 2017 13:35:11 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1df4d8-0002mn-7N; Tue, 08 Aug 2017 13:33:06 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1df4d7-0002mG-MQ for xen-devel@lists.xenproject.org; Tue, 08 Aug 2017 13:33:05 +0000 Received: from [193.109.254.147] by server-5.bemta-6.messagelabs.com id 5F/5D-03368-19DB9895; Tue, 08 Aug 2017 13:33:05 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFuplkeJIrShJLcpLzFFi42JxWrohUnfC3s5 Ig+ZFNhbft0xmcmD0OPzhCksAYxRrZl5SfkUCa8akL4vYC07LV5xdsoC5gbFDoouRg0NCwF/i 6we3LkZODjYBA4kV068ygoRFBFQkbu81AAkzC1RLPGprZQSxhQUCJO7OPgxWwgJU0jmDDyTMK 2ArcfJiLxuILSEgL9G/YzkTiM0pYCdx989XdpByIaCalSvlQMJCAmoSNxYuY4FoFZQ4OfMJC8 QmCYmDL14wT2DknYUkNQtJagEj0ypGjeLUorLUIl1DU72kosz0jJLcxMwcXUMDM73c1OLixPT UnMSkYr3k/NxNjMCgYQCCHYzflgUcYpTkYFIS5d2k3RkpxJeUn1KZkVicEV9UmpNafIhRhoND SYJXdA9QTrAoNT21Ii0zBxi+MGkJDh4lEV49kDRvcUFibnFmOkTqFKMux6sJ/78xCbHk5eelS onzyoIUCYAUZZTmwY2AxdIlRlkpYV5GoKOEeApSi3IzS1DlXzGKczAqCfOagEzhycwrgdv0Cu gIJqAjInzBjihJREhJNTAyMFZt9W5/ei6oboMjQxxj/+Keg6eCd6kkXf2136LB8XHYhmlrl+r 5B20Qm7/QgXnx8vUGpxLkd7iqrF7Gunhrrvul1lMycYf//A6fFrCFn2eXfmw0012Bt5cv/z2Q /KfwpXWXue7/k7FspiwGkpuu//ObFHx3WlFY77YT6QxXeTpKOhbO+BqjxFKckWioxVxUnAgAy CX8ZqACAAA= X-Env-Sender: prvs=386dc83ae=anthony.perard@citrix.com X-Msg-Ref: server-6.tower-27.messagelabs.com!1502199182!111049053!2 X-Originating-IP: [66.165.176.89] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogNjYuMTY1LjE3Ni44OSA9PiAyMDMwMDc=\n, received_headers: No Received headers X-StarScan-Received: X-StarScan-Version: 9.4.45; banners=-,-,- X-VirusChecked: Checked Received: (qmail 44258 invoked from network); 8 Aug 2017 13:33:04 -0000 Received: from smtp.citrix.com (HELO SMTP.CITRIX.COM) (66.165.176.89) by server-6.tower-27.messagelabs.com with RC4-SHA encrypted SMTP; 8 Aug 2017 13:33:04 -0000 X-IronPort-AV: E=Sophos;i="5.41,343,1498521600"; d="scan'208";a="434704122" From: Anthony PERARD To: Date: Tue, 8 Aug 2017 14:33:00 +0100 Message-ID: <20170808133300.2277-4-anthony.perard@citrix.com> X-Mailer: git-send-email 2.14.0 In-Reply-To: <20170808133300.2277-1-anthony.perard@citrix.com> References: <20170808133300.2277-1-anthony.perard@citrix.com> MIME-Version: 1.0 Cc: Anthony PERARD , Andrew Cooper , Jan Beulich Subject: [Xen-devel] [PATCH v3 3/3] x86/vlapic: Apply change to TDCR right away to the timer X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP The description in the Intel SDM of how the divide configuration register is used: "The APIC timer frequency will be the processor's bus clock or core crystal clock frequency divided by the value specified in the divide configuration register." Observation of baremetal shown that when the TDCR is change, the TMCCT does not change or make a big jump in value, but the rate at which it count down change. The patch update the emulation to APIC timer to so that a change to the divide configuration would be reflected in the value of the counter and when the next interrupt is triggered. Signed-off-by: Anthony PERARD --- Changes in V3: - do the calculation when the divisor is change only if delta is !0. --- xen/arch/x86/hvm/vlapic.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/xen/arch/x86/hvm/vlapic.c b/xen/arch/x86/hvm/vlapic.c index 7a5fbb40cd..4bfc53eab7 100644 --- a/xen/arch/x86/hvm/vlapic.c +++ b/xen/arch/x86/hvm/vlapic.c @@ -672,12 +672,13 @@ static void vlapic_tdt_pt_cb(struct vcpu *v, void *data) /* * This function is used when a register related to the APIC timer is updated. * It expects the new value for the register TMICT to be set *before* - * being called. + * being called, and the previous value of the divisor (calculated from TDCR) + * to be passed as argument. * It expect the new value of LVTT to be set *after* being called, with this * new values passed as parameter (only APIC_TIMER_MODE_MASK bits matter). */ static void vlapic_update_timer(struct vlapic *vlapic, uint32_t lvtt, - bool tmict_updated) + bool tmict_updated, uint32_t old_divisor) { uint64_t period, delta = 0; bool is_oneshot, is_periodic; @@ -686,7 +687,7 @@ static void vlapic_update_timer(struct vlapic *vlapic, uint32_t lvtt, is_oneshot = (lvtt & APIC_TIMER_MODE_MASK) == APIC_TIMER_MODE_ONESHOT; period = (uint64_t)vlapic_get_reg(vlapic, APIC_TMICT) - * APIC_BUS_CYCLE_NS * vlapic->hw.timer_divisor; + * APIC_BUS_CYCLE_NS * old_divisor; /* Calculate the next time the timer should trigger an interrupt. */ if ( tmict_updated ) @@ -705,6 +706,13 @@ static void vlapic_update_timer(struct vlapic *vlapic, uint32_t lvtt, if ( delta && (is_oneshot || is_periodic) ) { + if ( vlapic->hw.timer_divisor != old_divisor ) + { + period = (uint64_t)vlapic_get_reg(vlapic, APIC_TMICT) + * APIC_BUS_CYCLE_NS * vlapic->hw.timer_divisor; + delta = delta * vlapic->hw.timer_divisor / old_divisor; + } + TRACE_2_LONG_3D(TRC_HVM_EMUL_LAPIC_START_TIMER, TRC_PAR_LONG(delta), TRC_PAR_LONG(is_periodic ? period : 0), vlapic->pt.irq); @@ -810,7 +818,7 @@ static void vlapic_reg_write(struct vcpu *v, } vlapic->pt.irq = val & APIC_VECTOR_MASK; - vlapic_update_timer(vlapic, val, false); + vlapic_update_timer(vlapic, val, false, vlapic->hw.timer_divisor); /* fallthrough */ case APIC_LVTTHMR: /* LVT Thermal Monitor */ @@ -839,15 +847,23 @@ static void vlapic_reg_write(struct vcpu *v, vlapic_set_reg(vlapic, APIC_TMICT, val); - vlapic_update_timer(vlapic, vlapic_get_reg(vlapic, APIC_LVTT), true); + vlapic_update_timer(vlapic, vlapic_get_reg(vlapic, APIC_LVTT), true, + vlapic->hw.timer_divisor); break; case APIC_TDCR: + { + uint32_t current_divisor = vlapic->hw.timer_divisor; + vlapic_set_tdcr(vlapic, val & 0xb); + + vlapic_update_timer(vlapic, vlapic_get_reg(vlapic, APIC_LVTT), false, + current_divisor); HVM_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER, "timer divisor is %#x", vlapic->hw.timer_divisor); break; } + } } static int vlapic_write(struct vcpu *v, unsigned long address,