From patchwork Fri Sep 29 01:06:08 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wanpeng Li X-Patchwork-Id: 9976971 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 7382A6032A for ; Fri, 29 Sep 2017 01:06:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 65A1429793 for ; Fri, 29 Sep 2017 01:06:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5951829797; Fri, 29 Sep 2017 01:06:15 +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=-6.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EE14729793 for ; Fri, 29 Sep 2017 01:06:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751918AbdI2BGN (ORCPT ); Thu, 28 Sep 2017 21:06:13 -0400 Received: from mail-pg0-f65.google.com ([74.125.83.65]:36208 "EHLO mail-pg0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752002AbdI2BGL (ORCPT ); Thu, 28 Sep 2017 21:06:11 -0400 Received: by mail-pg0-f65.google.com with SMTP id d8so3549744pgt.3 for ; Thu, 28 Sep 2017 18:06:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=Y2YN/HiW/jB1EYLwfppSw+VG07kf/vvTbLXYfFygzHo=; b=ac1OhFh1WhGzsVIG7GN8Y36uINYY0QxHvy/P4GQpfJShl3vNUA87bJlLoV+D5f2L5n 7jYJPw/NNb6HXtaL/PfzKqmbww8YvFnrNl7jhAgXT9v5+LMX9YmJk74V2gK3x1mgUbl3 m6/IYKRwuLcVsbB2lj39uMRwT7KYciXOXDDLhnglUqX3KisPBUVe4txxJm4iaWlswM5d zgKtQ2LrIjqtZQYDEzZkipsQ9nleJHGHCNEQ+JIBoiLvbzDmXpWBhS/iXREibaDgA5LJ z+WM3JY5JgeaU9bB7EDFaQh8R9ekAqafU5HUzuwyKAU8LDa84ETXJyjCRr1B3pEsfcvi SpFQ== 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; bh=Y2YN/HiW/jB1EYLwfppSw+VG07kf/vvTbLXYfFygzHo=; b=q6LR1Vxdtuee2KNJuiqtHRxu65cB5h39HiouPvviBEusZ1Zd74MYrPJT7tX2sCLIyX +x0xUxPCBl1RCl1s+IPA0HRwPjn7CQtIFGE4iLjmQtEkCiknvXruknlJ4KKHnURi/8Zm H6NOsZjJTwK/QfvyjHVhexXawE2eLwXLKjp33w09xf/oaSUJHwX5o3q87s7PwgyiOAEI 8/tmY2KOyBjbgG1XzOmj6O6FbUMYrAzPgvO1NfYztI+Vy2HsttFeKOmlCK5ki97eYZAo j7HnYITF9b0ilcSQhZ27YV8NFbqEtE6ttQbrpeoSOJ3uIF++AU25/2u54OTWcRHkoyzc 3agg== X-Gm-Message-State: AHPjjUiRLae7BVuZpAxJEPys5w/ZKMrsquqluWKT7jBQOExHd8nl/PqL NdF6+c8Swpes0ttLucA9+6cjQA== X-Google-Smtp-Source: AOwi7QAD9N04geQwvClvTOyoYwVTo9dI1aGVlmStKYQDZS0mU9eXL5BG3JIa5nXnb1EZPe8K8Y2NcA== X-Received: by 10.98.186.6 with SMTP id k6mr5889168pff.166.1506647171295; Thu, 28 Sep 2017 18:06:11 -0700 (PDT) Received: from localhost ([203.205.141.123]) by smtp.gmail.com with ESMTPSA id g16sm4367679pgn.62.2017.09.28.18.06.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 28 Sep 2017 18:06:10 -0700 (PDT) From: Wanpeng Li X-Google-Original-From: Wanpeng Li To: kvm@vger.kernel.org Cc: Paolo Bonzini , =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= , Wanpeng Li Subject: [kvm-unit-tests PATCH] x86: apic: add apic timer mode transition test Date: Thu, 28 Sep 2017 18:06:08 -0700 Message-Id: <1506647168-2846-1-git-send-email-wanpeng.li@hotmail.com> X-Mailer: git-send-email 2.7.4 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Wanpeng Li Add apic timer mode transition test. Signed-off-by: Wanpeng Li --- lib/x86/apic-defs.h | 1 + x86/apic.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) diff --git a/lib/x86/apic-defs.h b/lib/x86/apic-defs.h index e0c3cca..a7bc6a0 100644 --- a/lib/x86/apic-defs.h +++ b/lib/x86/apic-defs.h @@ -91,6 +91,7 @@ #define APIC_TIMER_BASE_CLKIN 0x0 #define APIC_TIMER_BASE_TMBASE 0x1 #define APIC_TIMER_BASE_DIV 0x2 +#define APIC_LVT_TIMER_MASK (3 << 17) #define APIC_LVT_TIMER_ONESHOT (0 << 17) #define APIC_LVT_TIMER_PERIODIC (1 << 17) #define APIC_LVT_TIMER_TSCDEADLINE (2 << 17) diff --git a/x86/apic.c b/x86/apic.c index eb78579..6cfb52d 100644 --- a/x86/apic.c +++ b/x86/apic.c @@ -458,6 +458,83 @@ static void test_physical_broadcast(void) report("APIC physical broadcast shorthand", broadcast_received(ncpus)); } +void wait_until_tmcct_is_zero(uint32_t initial_count, bool stop_when_half) +{ + uint32_t tmcct = apic_read(APIC_TMCCT); + + if (tmcct) { + while (tmcct > (initial_count / 2)) + tmcct = apic_read(APIC_TMCCT); + + if ( stop_when_half ) + return; + + /* Wait until the counter reach 0 or wrap-around */ + while ( tmcct <= (initial_count / 2) && tmcct > 0 ) + tmcct = apic_read(APIC_TMCCT); + } +} + +static inline void apic_change_mode(unsigned long new_mode) +{ + uint32_t lvtt; + + lvtt = apic_read(APIC_LVTT); + apic_write(APIC_LVTT, (lvtt & ~APIC_LVT_TIMER_MASK) | new_mode); +} + +static void test_apic_change_mode() +{ + uint32_t tmict = 0x999999; + + printf("starting apic change mode\n"); + + apic_write(APIC_TMICT, tmict); + + apic_change_mode(APIC_LVT_TIMER_PERIODIC); + + report("TMICT value reset", apic_read(APIC_TMICT) == tmict); + + /* Testing one-shot */ + apic_change_mode(APIC_LVT_TIMER_ONESHOT); + apic_write(APIC_TMICT, tmict); + report("TMCCT should have a non-zero value", apic_read(APIC_TMCCT)); + + wait_until_tmcct_is_zero(tmict, false); + report("TMCCT should have reached 0", !apic_read(APIC_TMCCT)); + + /* + * Write TMICT before changing mode from one-shot to periodic TMCCT should + * be reset to TMICT periodicly + */ + apic_write(APIC_TMICT, tmict); + wait_until_tmcct_is_zero(tmict, true); + apic_change_mode(APIC_LVT_TIMER_PERIODIC); + report("TMCCT should have a non-zero value", apic_read(APIC_TMCCT)); + + /* + * After the change of mode, the counter should not be reset and continue + * counting down from where it was + */ + report("TMCCT should not be reset to TMICT value", apic_read(APIC_TMCCT) < (tmict / 2)); + wait_until_tmcct_is_zero(tmict, false); + report("TMCCT should be reset to the initial-count", apic_read(APIC_TMCCT) > (tmict / 2)); + + wait_until_tmcct_is_zero(tmict, true); + /* + * Keep the same TMICT and change timer mode to one-shot + * TMCCT should be > 0 and count-down to 0 + */ + apic_change_mode(APIC_LVT_TIMER_ONESHOT); + report("TMCCT should not be reset to init", apic_read(APIC_TMCCT) < (tmict / 2)); + wait_until_tmcct_is_zero(tmict, false); + report("TMCCT should have reach zero", !apic_read(APIC_TMCCT)); + + /* now tmcct == 0 and tmict != 0 */ + apic_change_mode(APIC_LVT_TIMER_PERIODIC); + report("TMCCT should stay at zero", !apic_read(APIC_TMCCT)); +} + int main() { setup_vm(); @@ -478,6 +555,7 @@ int main() test_multiple_nmi(); test_apic_timer_one_shot(); + test_apic_change_mode(); test_tsc_deadline_timer(); return report_summary();