From patchwork Sat Jan 4 17:59:08 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kiszka X-Patchwork-Id: 3434301 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 07665C02DC for ; Sat, 4 Jan 2014 18:00:12 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id CF7A320158 for ; Sat, 4 Jan 2014 18:00:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A936F2014A for ; Sat, 4 Jan 2014 18:00:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754371AbaADR7a (ORCPT ); Sat, 4 Jan 2014 12:59:30 -0500 Received: from mout.web.de ([212.227.15.4]:63814 "EHLO mout.web.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754064AbaADR73 (ORCPT ); Sat, 4 Jan 2014 12:59:29 -0500 Received: from mchn199C.home ([95.157.58.223]) by smtp.web.de (mrweb004) with ESMTPSA (Nemesis) id 0MASfy-1W6gWI0VFC-00BeHm for ; Sat, 04 Jan 2014 18:59:28 +0100 From: Jan Kiszka To: Gleb Natapov , Paolo Bonzini , Marcelo Tosatti Cc: kvm Subject: [PATCH 02/13] VMX: Extend preemption timer tests Date: Sat, 4 Jan 2014 18:59:08 +0100 Message-Id: <0a5a011b73361a016243fd436726995f63e511cb.1388858359.git.jan.kiszka@web.de> X-Mailer: git-send-email 1.8.1.1.298.ge7eed54 In-Reply-To: References: In-Reply-To: References: X-Provags-ID: V03:K0:Jp/n3z0sQ2g1bkhCjS/X9kUws/xkkaYX0HFF48fmpS174lpBGC3 JYTbQaxOU6uSdFc1ev5tXZOhHbewpQRaxJZWMxDAHnvUTSdOaNC90itQL3lxxDNsHoBiamm u9OBP2QIDbTBu9h12TSkw3z//XJnNdWU5AtAw/LYn2X1RGfaEhhpr4ueW7tUjWFzPm3OSGl upNW3+YQII+LZt97VMENA== Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Spam-Status: No, score=-7.3 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Jan Kiszka This checks that we properly expire the preemption timer while the guest is in HLT state and that we do not progress guest execution of the preemption timer is activated with a timer value of 0. Signed-off-by: Jan Kiszka --- x86/vmx_tests.c | 84 +++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 64 insertions(+), 20 deletions(-) diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c index 70efb50..0077f3f 100644 --- a/x86/vmx_tests.c +++ b/x86/vmx_tests.c @@ -99,6 +99,7 @@ int vmenter_exit_handler() u32 preempt_scale; volatile unsigned long long tsc_val; volatile u32 preempt_val; +u64 saved_rip; int preemption_timer_init() { @@ -126,17 +127,24 @@ void preemption_timer_main() if (get_stage() == 1) vmcall(); } - while (1) { + set_stage(1); + while (get_stage() == 1) { if (((rdtsc() - tsc_val) >> preempt_scale) > 10 * preempt_val) { set_stage(2); vmcall(); } } + tsc_val = rdtsc(); + asm volatile ("hlt"); + vmcall(); + set_stage(5); + vmcall(); } int preemption_timer_exit_handler() { + bool guest_halted; u64 guest_rip; ulong reason; u32 insn_len; @@ -147,33 +155,69 @@ int preemption_timer_exit_handler() insn_len = vmcs_read(EXI_INST_LEN); switch (reason) { case VMX_PREEMPT: - if (((rdtsc() - tsc_val) >> preempt_scale) < preempt_val) - report("Preemption timer", 0); - else - report("Preemption timer", 1); + switch (get_stage()) { + case 1: + case 2: + report("busy-wait for preemption timer", + ((rdtsc() - tsc_val) >> preempt_scale) >= + preempt_val); + set_stage(3); + vmcs_write(PREEMPT_TIMER_VALUE, preempt_val); + return VMX_TEST_RESUME; + case 3: + guest_halted = + (vmcs_read(GUEST_ACTV_STATE) == ACTV_HLT); + report("preemption timer during hlt", + ((rdtsc() - tsc_val) >> preempt_scale) >= + preempt_val && guest_halted); + set_stage(4); + vmcs_write(PIN_CONTROLS, + vmcs_read(PIN_CONTROLS) & ~PIN_PREEMPT); + vmcs_write(GUEST_ACTV_STATE, ACTV_ACTIVE); + return VMX_TEST_RESUME; + case 4: + report("preemption timer with 0 value", + saved_rip == guest_rip); + break; + default: + printf("Invalid stage.\n"); + print_vmexit_info(); + break; + } break; case VMX_VMCALL: + vmcs_write(GUEST_RIP, guest_rip + insn_len); switch (get_stage()) { case 0: - if (vmcs_read(PREEMPT_TIMER_VALUE) != preempt_val) - report("Save preemption value", 0); - else { - set_stage(get_stage() + 1); - ctrl_exit = (vmcs_read(EXI_CONTROLS) | - EXI_SAVE_PREEMPT) & ctrl_exit_rev.clr; - vmcs_write(EXI_CONTROLS, ctrl_exit); - } - vmcs_write(GUEST_RIP, guest_rip + insn_len); + report("Keep preemption value", + vmcs_read(PREEMPT_TIMER_VALUE) == preempt_val); + set_stage(1); + vmcs_write(PREEMPT_TIMER_VALUE, preempt_val); + ctrl_exit = (vmcs_read(EXI_CONTROLS) | + EXI_SAVE_PREEMPT) & ctrl_exit_rev.clr; + vmcs_write(EXI_CONTROLS, ctrl_exit); return VMX_TEST_RESUME; case 1: - if (vmcs_read(PREEMPT_TIMER_VALUE) >= preempt_val) - report("Save preemption value", 0); - else - report("Save preemption value", 1); - vmcs_write(GUEST_RIP, guest_rip + insn_len); + report("Save preemption value", + vmcs_read(PREEMPT_TIMER_VALUE) < preempt_val); return VMX_TEST_RESUME; case 2: - report("Preemption timer", 0); + report("busy-wait for preemption timer", 0); + set_stage(3); + vmcs_write(PREEMPT_TIMER_VALUE, preempt_val); + return VMX_TEST_RESUME; + case 3: + report("preemption timer during hlt", 0); + set_stage(4); + /* fall through */ + case 4: + vmcs_write(PIN_CONTROLS, + vmcs_read(PIN_CONTROLS) | PIN_PREEMPT); + vmcs_write(PREEMPT_TIMER_VALUE, 0); + saved_rip = guest_rip + insn_len; + return VMX_TEST_RESUME; + case 5: + report("preemption timer with 0 value (vmcall stage 5)", 0); break; default: // Should not reach here