public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Eduardo Habkost <ehabkost-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
To: Avi Kivity <avi-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Cc: Andrew Morton <akpm-3NddpPZAyC0@public.gmane.org>,
	Eduardo Habkost
	<ehabkost-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>,
	kvm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	Haren Myneni <hbabu-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>,
	Simon Horman <horms-/R6kz+dDXgpPR4JQBCEnsQ@public.gmane.org>,
	"Eric W. Biederman"
	<ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>,
	Vivek Goyal <vgoyal-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Subject: [PATCH 1/6] kdump: crash-time virt disable function
Date: Thu, 30 Oct 2008 11:34:41 -0200	[thread overview]
Message-ID: <1225373687-6960-2-git-send-email-ehabkost@redhat.com> (raw)
In-Reply-To: <1225373687-6960-1-git-send-email-ehabkost-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

This patch adds an interface to set a function to be called on crash time,
on each CPU. The function will be set by code that enables virtualization
extensions on the CPUs (i.e. KVM).  It will be called once on each CPU
by machine_crash_shutdown(), and should do the very least to disable
virt extensions on the CPU where it is being called.

The function will be used by KVM to disable virtualization before halting
the CPUs, otherwise the booting of the kdump kernel may hang. It does
hang, when vmx is enabled, and I wouldn't be surprised if having svm
enabled also causes problems.

The functions that set the function pointer uses RCU synchronization,
just in case the crash NMI is triggered while KVM is unloading.

We can't just use the same notifiers used at reboot time (that are used
by non-crash-dump kexec), because at crash time some CPUs may have IRQs
disabled, so we can't use IPIs. The crash shutdown code use NMIs to
tell the other CPUs to be halted, so the notifier call is hooked into
the CPU halting code that is on the crash shutdown NMI handler.

Signed-off-by: Eduardo Habkost <ehabkost-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 arch/x86/include/asm/virtext.h |   24 +++++++++++++
 arch/x86/kernel/crash.c        |   71 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 95 insertions(+), 0 deletions(-)
 create mode 100644 arch/x86/include/asm/virtext.h

diff --git a/arch/x86/include/asm/virtext.h b/arch/x86/include/asm/virtext.h
new file mode 100644
index 0000000..773037c
--- /dev/null
+++ b/arch/x86/include/asm/virtext.h
@@ -0,0 +1,24 @@
+/* virtualization extensions handling code
+ */
+#ifndef _ASM_X86_VIRTEX_H
+#define _ASM_X86_VIRTEX_H
+
+#ifdef CONFIG_KEXEC
+
+int set_virt_disable_func(void (*fn)(unsigned int cpu));
+void clear_virt_disable_func(void);
+
+#else /* !CONFIG_KEXEC */
+
+inline int set_virt_disable_func(void (*fn)(unsigned int cpu))
+{
+	return 0;
+}
+
+inline void clear_virt_disable_func(void)
+{
+}
+
+#endif /* CONFIG_KEXEC */
+
+#endif /* _ASM_X86_VIRTEX_H */
diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
index 2685538..6ed28e9 100644
--- a/arch/x86/kernel/crash.c
+++ b/arch/x86/kernel/crash.c
@@ -16,6 +16,7 @@
 #include <linux/delay.h>
 #include <linux/elf.h>
 #include <linux/elfcore.h>
+#include <linux/module.h>
 
 #include <asm/processor.h>
 #include <asm/hardirq.h>
@@ -32,6 +33,72 @@
 /* This keeps a track of which one is crashing cpu. */
 static int crashing_cpu;
 
+static DEFINE_SPINLOCK(virt_disable_lock);
+static void (*virt_disable_fn)(unsigned int cpu);
+
+/**	set function to be called to disable virtualization on crash
+ *
+ *	Registers a function to be called when CPUs are being halted at
+ *	machine_crash_shutdown().
+ *
+ *	There is only one function pointer, so the function
+ *	is reserved to be set by the KVM module at load time, before
+ *	enabling virtualization.
+ *
+ *	The function is called once on each online CPU, possibly
+ *	from a NMI handler. It should do the very least to allow the CPU
+ *	to be halted before booting the kdump kernel, as the kernel has
+ *	just crashed.
+ */
+int set_virt_disable_func(void (*fn)(unsigned int cpu))
+{
+	int r = 0;
+
+	spin_lock(&virt_disable_lock);
+	if (!virt_disable_fn)
+		rcu_assign_pointer(virt_disable_fn, fn);
+	else
+		r = -EEXIST;
+	spin_unlock(&virt_disable_lock);
+
+	return r;
+}
+EXPORT_SYMBOL(set_virt_disable_func);
+
+/** clear the virt_disable function set by set_virt_disable_func()
+ *
+ * You must call this function only if you sucessfully set
+ * the virt_disable function on a previous set_virt_disable_func()
+ * call.
+ *
+ * This function will use synchronize_sched() to wait until it's safe
+ * to free any data or code related to the previous existing virt_disable
+ * func, before returning.
+ */
+void clear_virt_disable_func(void)
+{
+	spin_lock(&virt_disable_lock);
+	rcu_assign_pointer(virt_disable_fn, NULL);
+	spin_unlock(&virt_disable_lock);
+
+	synchronize_sched();
+}
+EXPORT_SYMBOL(clear_virt_disable_func);
+
+/* Disable virtualization extensions if needed
+ *
+ * Runs thefunction set by set_virt_disable_func()
+ *
+ * Must be called on the CPU that is being halted.
+ */
+void virt_disable(unsigned int cpu)
+{
+	void (*fn)(unsigned int);
+	fn = rcu_dereference(virt_disable_fn);
+	if (fn)
+		fn(cpu);
+}
+
 #if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC)
 static atomic_t waiting_for_crash_ipi;
 
@@ -65,6 +132,8 @@ static int crash_nmi_callback(struct notifier_block *self,
 	}
 #endif
 	crash_save_cpu(regs, cpu);
+
+	virt_disable(cpu);
 	disable_local_APIC();
 	atomic_dec(&waiting_for_crash_ipi);
 	/* Assume hlt works */
@@ -134,6 +203,8 @@ void native_machine_crash_shutdown(struct pt_regs *regs)
 	/* Make a note of crashing cpu. Will be used in NMI callback.*/
 	crashing_cpu = safe_smp_processor_id();
 	nmi_shootdown_cpus();
+	virt_disable(crashing_cpu);
+
 	lapic_shutdown();
 #if defined(CONFIG_X86_IO_APIC)
 	disable_IO_APIC();
-- 
1.5.5.GIT

  parent reply	other threads:[~2008-10-30 13:34 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-10-30 13:34 [PATCH 0/6] kdump: disable virtualization extensions on crash (v2) Eduardo Habkost
     [not found] ` <1225373687-6960-1-git-send-email-ehabkost-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2008-10-30 13:34   ` Eduardo Habkost [this message]
     [not found]     ` <1225373687-6960-2-git-send-email-ehabkost-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2008-10-30 13:50       ` [PATCH 1/6] kdump: crash-time virt disable function Avi Kivity
     [not found]         ` <4909BBA7.1020307-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2008-10-30 16:24           ` Eduardo Habkost
2008-10-30 13:34   ` [PATCH 2/6] kvm_x86_ops: crash_hardware_disable() operation Eduardo Habkost
2008-10-30 13:34   ` [PATCH 3/6] kvm: svm: set crash_hardware_disable to svm_hardware_disable Eduardo Habkost
2008-10-30 13:34   ` [PATCH 4/6] kvm: vmx: crash_hardware_disable function Eduardo Habkost
2008-10-30 13:34   ` [PATCH 5/6] kvmx: x86: set kvm_x86_ops earlier on kvm_arch_init() Eduardo Habkost
2008-10-30 13:34   ` [PATCH 6/6] kvm: x86: set kdump virt_disable function on initialization Eduardo Habkost
2008-10-30 13:52   ` [PATCH 0/6] kdump: disable virtualization extensions on crash (v2) Avi Kivity

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=1225373687-6960-2-git-send-email-ehabkost@redhat.com \
    --to=ehabkost-h+wxahxf7alqt0dzr+alfa@public.gmane.org \
    --cc=akpm-3NddpPZAyC0@public.gmane.org \
    --cc=avi-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org \
    --cc=ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org \
    --cc=hbabu-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org \
    --cc=horms-/R6kz+dDXgpPR4JQBCEnsQ@public.gmane.org \
    --cc=kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
    --cc=kvm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=vgoyal-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox