All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Radim Krčmář" <rkrcmar@redhat.com>
To: Eduardo Habkost <ehabkost@redhat.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	peterx@redhat.com, Andrew Jones <drjones@redhat.com>,
	kvm@vger.kernel.org
Subject: Re: kvm_pv_unhalt and kernel_irqchip=off
Date: Wed, 10 Aug 2016 22:58:31 +0200	[thread overview]
Message-ID: <20160810205830.GB27257@potion> (raw)
In-Reply-To: <20160810190412.GA8001@potion>

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<---
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

  reply	other threads:[~2016-08-10 20:59 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-08-10 18:27 kvm_pv_unhalt and kernel_irqchip=off Eduardo Habkost
2016-08-10 19:04 ` Radim Krčmář
2016-08-10 20:58   ` Radim Krčmář [this message]
2016-08-12 18:37   ` GET_SUPPORTED_CPUID and irqchip (was Re: kvm_pv_unhalt and kernel_irqchip=off) Eduardo Habkost
2016-08-13 12:43     ` Radim Krčmář
2016-08-15 13:03       ` Eduardo Habkost
2016-08-15 13:21         ` Paolo Bonzini
2016-08-15 17:50         ` Radim Krčmář
2016-08-15 18:00           ` Eduardo Habkost
2016-08-15 18:32             ` Radim Krčmář

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160810205830.GB27257@potion \
    --to=rkrcmar@redhat.com \
    --cc=drjones@redhat.com \
    --cc=ehabkost@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=mtosatti@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peterx@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.