[Precise SRU] Fix oops in arch_trigger_all_cpu_backtrace
Stefan Bader
stefan.bader at canonical.com
Wed May 8 14:07:55 UTC 2013
Although there is one of the hooks that looks not completely right,
this is the upstream version (without the unnecessary declaration
in smp.h) which seemed to cause no issues. I was not able to see
any impact either. From previous tests of a kernel with this patch
it was said to resolve the issue.
This was added in 3.5 so it is only required for 3.2.
-Stefan
---
>From 1e78425a8ddace467b9f4ef33a87ad81d476a319 Mon Sep 17 00:00:00 2001
From: Ben Guthro <ben at guthro.net>
Date: Sat, 21 Apr 2012 00:11:04 +0800
Subject: [PATCH] xen: implement apic ipi interface
Map native ipi vector to xen vector.
Implement apic ipi interface with xen_send_IPI_one.
Tested-by: Steven Noonan <steven at uplinklabs.net>
Signed-off-by: Ben Guthro <ben at guthro.net>
Signed-off-by: Lin Ming <mlin at ss.pku.edu.cn>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
BugLink: http://bugs.launchpad.net/bugs/1168350
(backported from f447d56d36af18c5104ff29dcb1327c0c0ac3634 upstream)
[v2: Drop physflat_send_IPI_allbutself declaration from xen/smp.h]
Signed-off-by: Stefan Bader <stefan.bader at canonical.com>
---
arch/x86/xen/enlighten.c | 9 ++++++
arch/x86/xen/smp.c | 81 +++++++++++++++++++++++++++++++++++++++++++---
arch/x86/xen/smp.h | 11 +++++++
3 files changed, 97 insertions(+), 4 deletions(-)
create mode 100644 arch/x86/xen/smp.h
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index bb03ff0..b284aa3 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -69,6 +69,7 @@
#include "xen-ops.h"
#include "mmu.h"
+#include "smp.h"
#include "multicalls.h"
EXPORT_SYMBOL_GPL(hypercall_page);
@@ -821,6 +822,14 @@ static void set_xen_basic_apic_ops(void)
apic->safe_wait_icr_idle = xen_safe_apic_wait_icr_idle;
apic->set_apic_id = xen_set_apic_id;
apic->get_apic_id = xen_get_apic_id;
+
+#ifdef CONFIG_SMP
+ apic->send_IPI_allbutself = xen_send_IPI_allbutself;
+ apic->send_IPI_mask_allbutself = xen_send_IPI_mask_allbutself;
+ apic->send_IPI_mask = xen_send_IPI_mask;
+ apic->send_IPI_all = xen_send_IPI_all;
+ apic->send_IPI_self = xen_send_IPI_self;
+#endif
}
#endif
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 9a23fff..36a143f 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -467,8 +467,8 @@ static void xen_smp_send_reschedule(int cpu)
xen_send_IPI_one(cpu, XEN_RESCHEDULE_VECTOR);
}
-static void xen_send_IPI_mask(const struct cpumask *mask,
- enum ipi_vector vector)
+static void __xen_send_IPI_mask(const struct cpumask *mask,
+ int vector)
{
unsigned cpu;
@@ -480,7 +480,7 @@ static void xen_smp_send_call_function_ipi(const struct cpumask *mask)
{
int cpu;
- xen_send_IPI_mask(mask, XEN_CALL_FUNCTION_VECTOR);
+ __xen_send_IPI_mask(mask, XEN_CALL_FUNCTION_VECTOR);
/* Make sure other vcpus get a chance to run if they need to. */
for_each_cpu(cpu, mask) {
@@ -493,10 +493,83 @@ static void xen_smp_send_call_function_ipi(const struct cpumask *mask)
static void xen_smp_send_call_function_single_ipi(int cpu)
{
- xen_send_IPI_mask(cpumask_of(cpu),
+ __xen_send_IPI_mask(cpumask_of(cpu),
XEN_CALL_FUNCTION_SINGLE_VECTOR);
}
+static inline int xen_map_vector(int vector)
+{
+ int xen_vector;
+
+ switch (vector) {
+ case RESCHEDULE_VECTOR:
+ xen_vector = XEN_RESCHEDULE_VECTOR;
+ break;
+ case CALL_FUNCTION_VECTOR:
+ xen_vector = XEN_CALL_FUNCTION_VECTOR;
+ break;
+ case CALL_FUNCTION_SINGLE_VECTOR:
+ xen_vector = XEN_CALL_FUNCTION_SINGLE_VECTOR;
+ break;
+ default:
+ xen_vector = -1;
+ printk(KERN_ERR "xen: vector 0x%x is not implemented\n",
+ vector);
+ }
+
+ return xen_vector;
+}
+
+void xen_send_IPI_mask(const struct cpumask *mask,
+ int vector)
+{
+ int xen_vector = xen_map_vector(vector);
+
+ if (xen_vector >= 0)
+ __xen_send_IPI_mask(mask, xen_vector);
+}
+
+void xen_send_IPI_all(int vector)
+{
+ int xen_vector = xen_map_vector(vector);
+
+ if (xen_vector >= 0)
+ __xen_send_IPI_mask(cpu_online_mask, xen_vector);
+}
+
+void xen_send_IPI_self(int vector)
+{
+ int xen_vector = xen_map_vector(vector);
+
+ if (xen_vector >= 0)
+ xen_send_IPI_one(smp_processor_id(), xen_vector);
+}
+
+void xen_send_IPI_mask_allbutself(const struct cpumask *mask,
+ int vector)
+{
+ unsigned cpu;
+ unsigned int this_cpu = smp_processor_id();
+
+ if (!(num_online_cpus() > 1))
+ return;
+
+ for_each_cpu_and(cpu, mask, cpu_online_mask) {
+ if (this_cpu == cpu)
+ continue;
+
+ xen_smp_send_call_function_single_ipi(cpu);
+ }
+}
+
+void xen_send_IPI_allbutself(int vector)
+{
+ int xen_vector = xen_map_vector(vector);
+
+ if (xen_vector >= 0)
+ xen_send_IPI_mask_allbutself(cpu_online_mask, xen_vector);
+}
+
static irqreturn_t xen_call_function_interrupt(int irq, void *dev_id)
{
irq_enter();
diff --git a/arch/x86/xen/smp.h b/arch/x86/xen/smp.h
new file mode 100644
index 0000000..c7c2d89
--- /dev/null
+++ b/arch/x86/xen/smp.h
@@ -0,0 +1,11 @@
+#ifndef _XEN_SMP_H
+
+extern void xen_send_IPI_mask(const struct cpumask *mask,
+ int vector);
+extern void xen_send_IPI_mask_allbutself(const struct cpumask *mask,
+ int vector);
+extern void xen_send_IPI_allbutself(int vector);
+extern void xen_send_IPI_all(int vector);
+extern void xen_send_IPI_self(int vector);
+
+#endif
--
1.7.9.5
More information about the kernel-team
mailing list