From patchwork Wed Aug 10 20:58:31 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?UmFkaW0gS3LEjW3DocWZ?= X-Patchwork-Id: 9274103 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 A8E4A600CA for ; Wed, 10 Aug 2016 20:59:56 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 976B625EA6 for ; Wed, 10 Aug 2016 20:59:56 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8BF1E26785; Wed, 10 Aug 2016 20:59:56 +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=-5.9 required=2.0 tests=BAYES_00,HK_RANDOM_FROM, RCVD_IN_DNSWL_HI 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 3821C26255 for ; Wed, 10 Aug 2016 20:59:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932634AbcHJU7w (ORCPT ); Wed, 10 Aug 2016 16:59:52 -0400 Received: from mx1.redhat.com ([209.132.183.28]:45680 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752921AbcHJU7F (ORCPT ); Wed, 10 Aug 2016 16:59:05 -0400 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1A59E883A4 for ; Wed, 10 Aug 2016 20:58:35 +0000 (UTC) Received: from potion (dhcp-1-206.brq.redhat.com [10.34.1.206]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id u7AKwVao012907; Wed, 10 Aug 2016 16:58:32 -0400 Received: by potion (sSMTP sendmail emulation); Wed, 10 Aug 2016 22:58:31 +0200 Date: Wed, 10 Aug 2016 22:58:31 +0200 From: Radim =?utf-8?B?S3LEjW3DocWZ?= To: Eduardo Habkost Cc: Marcelo Tosatti , Paolo Bonzini , peterx@redhat.com, Andrew Jones , kvm@vger.kernel.org Subject: Re: kvm_pv_unhalt and kernel_irqchip=off Message-ID: <20160810205830.GB27257@potion> References: <20160810182704.GE5627@thinpad.lan.raisama.net> <20160810190412.GA8001@potion> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20160810190412.GA8001@potion> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Wed, 10 Aug 2016 20:58:35 +0000 (UTC) Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 2016-08-10 21:04+0200, Radim Krčmář: >> Related question: is there any kvm-unit-test test for >> kvm_pv_unhalt? > > Not that I know of, thanks for the request. I attached a simple test below. It will likely need some modifications after the bug is fixed in QEMU and/or KVM. For a fix in KVM, I used the solution from another feature that doesn't work with irqchip=off, x2APIC. Jokes aside, we can fix them both because SET_CPUID cannot be called after CREATE_IRQCHIP. I'll do so tomorrow. ---8<--- --- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/lib/x86/processor.h b/lib/x86/processor.h index ee7f180237b1..f33c680e5dbf 100644 --- a/lib/x86/processor.h +++ b/lib/x86/processor.h @@ -402,6 +402,11 @@ static inline void safe_halt(void) asm volatile("sti; hlt"); } +static inline void cpu_relax(void) +{ + asm volatile ("rep; nop"); +} + static inline u32 read_pkru(void) { unsigned int eax, edx; diff --git a/x86/Makefile.common b/x86/Makefile.common index 356d879a986b..6a3bbc86df68 100644 --- a/x86/Makefile.common +++ b/x86/Makefile.common @@ -45,6 +45,7 @@ tests-common = $(TEST_DIR)/vmexit.flat $(TEST_DIR)/tsc.flat \ $(TEST_DIR)/tsc_adjust.flat $(TEST_DIR)/asyncpf.flat \ $(TEST_DIR)/init.flat $(TEST_DIR)/smap.flat \ $(TEST_DIR)/hyperv_synic.flat $(TEST_DIR)/hyperv_stimer.flat \ + $(TEST_DIR)/pv_unhalt.flat \ ifdef API tests-common += api/api-sample diff --git a/x86/pv_unhalt.c b/x86/pv_unhalt.c new file mode 100644 index 000000000000..d717e309eab0 --- /dev/null +++ b/x86/pv_unhalt.c @@ -0,0 +1,73 @@ +#include "libcflat.h" +#include "vm.h" +#include "desc.h" +#include "smp.h" + +/* Intel and AMD hypercalls should be interchangeable. */ +#define KVM_HYPERCALL ".byte 0x0f,0x01,0xc1" + +#define KVM_HC_KICK_CPU 5 + +#define KVM_CPUID_FEATURES 0x40000001 +#define KVM_FEATURE_PV_UNHALT (1 << 7) + +static volatile bool pv_unhalt_works; + +static inline long kvm_hypercall2(unsigned int nr, unsigned long p1, + unsigned long p2) +{ + long ret; + asm volatile(KVM_HYPERCALL + : "=a"(ret) + : "a"(nr), "b"(p1), "c"(p2) + : "memory"); + return ret; +} + +static void halt(void * nothing) +{ + asm volatile("cli; hlt; sti" ::: "memory"); + + pv_unhalt_works = true; +} + +static void test_pv_unhalt(void) +{ + unsigned long delay; + + if (cpu_count() < 2) { + report_skip("pv unhalt"); + return; + } + + /* XXX: KVM_CPUID_FEATURES can have a different base offset */ + if (!(cpuid(KVM_CPUID_FEATURES).a & KVM_FEATURE_PV_UNHALT)) { + /* TODO: use argv to decide whether the presence of pv_unhalt + * is a skip or pass? */ + report("pv unhalt", 1); + return; + } + + on_cpu_async(1, halt, 0); + /* we need a small delay because CPU1 can't notify that it halted */ + for (delay = 1<<28; delay; delay--) + cpu_relax(); + + kvm_hypercall2(KVM_HC_KICK_CPU, 0, 1); + + /* TODO: sane delay loops (ignoring pv_unhalt_works is fine) */ + for (delay = 1<<28; delay && !pv_unhalt_works; delay--) + cpu_relax(); + + report("pv unhalt", pv_unhalt_works); +} + +int main(int ac, char **av) +{ + setup_vm(); + smp_init(); + + test_pv_unhalt(); + + return report_summary(); +} diff --git a/x86/unittests.cfg b/x86/unittests.cfg index 60747cfca94e..6fe688d01357 100644 --- a/x86/unittests.cfg +++ b/x86/unittests.cfg @@ -197,3 +197,13 @@ extra_params = -cpu kvm64,hv_synic -device hyperv-testdev file = hyperv_stimer.flat smp = 2 extra_params = -cpu kvm64,hv_time,hv_synic,hv_stimer -device hyperv-testdev + +[pv_unhalt] +file = pv_unhalt.flat +smp = 2 +extra_params = -cpu kvm64,+kvm_pv_unhalt + +[pv_unhalt_irqchip_off] +file = pv_unhalt.flat +smp = 2 +extra_params = -cpu kvm64,+kvm_pv_unhalt -machine kernel_irqchip=off