[kernel/f17] Implement xen apic_ops to fix early crash in Xen Dom0 (rhbz 804347)

Josh Boyer jwboyer at fedoraproject.org
Tue Mar 27 17:48:55 UTC 2012


commit 46ad899861a69fc60dd41aafd27dd0d54f5b6a5e
Author: Josh Boyer <jwboyer at redhat.com>
Date:   Tue Mar 27 12:13:33 2012 -0400

    Implement xen apic_ops to fix early crash in Xen Dom0 (rhbz 804347)

 kernel.spec                                        |   19 ++-
 x86-add-io_apic_ops-to-allow-interception.patch    |  135 ++++++++++
 ...ic_ops-Replace-apic_ops-with-x86_apic_ops.patch |  258 ++++++++++++++++++++
 ...register-checks-for-bogus-io-apic-entries.patch |   93 +++++++
 xen-x86-Implement-x86_apic_ops.patch               |   85 +++++++
 5 files changed, 589 insertions(+), 1 deletions(-)
---
diff --git a/kernel.spec b/kernel.spec
index 971133b..a70c0e1 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -54,7 +54,7 @@ Summary: The Linux kernel
 # For non-released -rc kernels, this will be appended after the rcX and
 # gitX tags, so a 3 here would become part of release "0.rcX.gitX.3"
 #
-%global baserelease 5
+%global baserelease 6
 %global fedora_build %{baserelease}
 
 # base_sublevel is the kernel version we're starting with and patching
@@ -770,6 +770,13 @@ Patch21305: mac80211-fix-possible-tid_rx-reorder_timer-use-after-free.patch
 #rhbz 804957 CVE-2012-1568
 Patch21306: shlib_base_randomize.patch
 
+Patch21350: x86-ioapic-add-register-checks-for-bogus-io-apic-entries.patch
+
+#rhbz 804347
+Patch21351: x86-add-io_apic_ops-to-allow-interception.patch
+Patch21352: x86-apic_ops-Replace-apic_ops-with-x86_apic_ops.patch
+Patch21353: xen-x86-Implement-x86_apic_ops.patch
+
 Patch21400: unhandled-irqs-switch-to-polling.patch
 
 Patch22000: weird-root-dentry-name-debug.patch
@@ -1489,6 +1496,13 @@ ApplyPatch unhandled-irqs-switch-to-polling.patch
 
 ApplyPatch weird-root-dentry-name-debug.patch
 
+ApplyPatch x86-ioapic-add-register-checks-for-bogus-io-apic-entries.patch
+
+#rhbz 804347
+ApplyPatch x86-add-io_apic_ops-to-allow-interception.patch
+ApplyPatch x86-apic_ops-Replace-apic_ops-with-x86_apic_ops.patch
+ApplyPatch xen-x86-Implement-x86_apic_ops.patch
+
 #rhbz 803809 CVE-2012-1179
 ApplyPatch mm-thp-fix-pmd_bad-triggering.patch
 
@@ -2334,6 +2348,9 @@ fi
 #    '-'      |  |
 #              '-'
 %changelog
+* Tue Mar 27 2012 Josh Boyer <jwboyer at redhat.com>
+- Implement xen apic_ops to fix early crash in Xen Dom0 (rhbz 804347)
+
 * Fri Mar 23 2012 Dave Jones <davej at redhat.com> 3.3.0-5
 - Apply patches that should solve the bluetooth use-after-free oopses. (rhbz 806033)
 
diff --git a/x86-add-io_apic_ops-to-allow-interception.patch b/x86-add-io_apic_ops-to-allow-interception.patch
new file mode 100644
index 0000000..c82d21f
--- /dev/null
+++ b/x86-add-io_apic_ops-to-allow-interception.patch
@@ -0,0 +1,135 @@
+From: Jeremy Fitzhardinge <jeremy.fitzhardinge at citrix.com>
+
+Xen dom0 needs to paravirtualize IO operations to the IO APIC, so add
+a io_apic_ops for it to intercept.  Do this as ops structure because
+there's at least some chance that another paravirtualized environment
+may want to intercept these.
+
+[ Impact: indirect IO APIC access via io_apic_ops ]
+
+Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge at citrix.com>
+Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
+Acked-by: Suresh Siddha <suresh.b.siddha at intel.com>
+---
+ arch/x86/include/asm/io_apic.h |    9 +++++++
+ arch/x86/kernel/apic/io_apic.c |   50 +++++++++++++++++++++++++++++++++++++--
+ 2 files changed, 56 insertions(+), 3 deletions(-)
+
+diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
+index 690d1cc..190d8c2 100644
+--- a/arch/x86/include/asm/io_apic.h
++++ b/arch/x86/include/asm/io_apic.h
+@@ -21,6 +21,15 @@
+ #define IO_APIC_REDIR_LEVEL_TRIGGER	(1 << 15)
+ #define IO_APIC_REDIR_MASKED		(1 << 16)
+ 
++struct io_apic_ops {
++	void (*init)(void);
++	unsigned int (*read)(unsigned int apic, unsigned int reg);
++	void (*write)(unsigned int apic, unsigned int reg, unsigned int value);
++	void (*modify)(unsigned int apic, unsigned int reg, unsigned int value);
++};
++
++void __init set_io_apic_ops(const struct io_apic_ops *);
++
+ /*
+  * The structure of the IO-APIC:
+  */
+diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
+index fb07275..bf120234 100644
+--- a/arch/x86/kernel/apic/io_apic.c
++++ b/arch/x86/kernel/apic/io_apic.c
+@@ -67,6 +67,25 @@
+ #define for_each_irq_pin(entry, head) \
+ 	for (entry = head; entry; entry = entry->next)
+ 
++static void __init __ioapic_init_mappings(void);
++static unsigned int __io_apic_read(unsigned int apic, unsigned int reg);
++static void __io_apic_write(unsigned int apic, unsigned int reg,
++			    unsigned int val);
++static void __io_apic_modify(unsigned int apic, unsigned int reg,
++			     unsigned int val);
++
++static struct io_apic_ops io_apic_ops = {
++	.init = __ioapic_init_mappings,
++	.read = __io_apic_read,
++	.write = __io_apic_write,
++	.modify = __io_apic_modify,
++};
++
++void __init set_io_apic_ops(const struct io_apic_ops *ops)
++{
++	io_apic_ops = *ops;
++}
++
+ /*
+  *      Is the SiS APIC rmw bug present ?
+  *      -1 = don't know, 0 = no, 1 = yes
+@@ -294,6 +313,24 @@ static void free_irq_at(unsigned int at, struct irq_cfg *cfg)
+ 	irq_free_desc(at);
+ }
+ 
++static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
++{
++	return io_apic_ops.read(apic, reg);
++}
++
++static inline void io_apic_write(unsigned int apic, unsigned int reg,
++				 unsigned int value)
++{
++	io_apic_ops.write(apic, reg, value);
++}
++
++static inline void io_apic_modify(unsigned int apic, unsigned int reg,
++				  unsigned int value)
++{
++	io_apic_ops.modify(apic, reg, value);
++}
++
++
+ struct io_apic {
+ 	unsigned int index;
+ 	unsigned int unused[3];
+@@ -314,14 +351,15 @@ static inline void io_apic_eoi(unsigned int apic, unsigned int vector)
+ 	writel(vector, &io_apic->eoi);
+ }
+ 
+-static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
++static unsigned int __io_apic_read(unsigned int apic, unsigned int reg)
+ {
+ 	struct io_apic __iomem *io_apic = io_apic_base(apic);
+ 	writel(reg, &io_apic->index);
+ 	return readl(&io_apic->data);
+ }
+ 
+-static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
++static void __io_apic_write(unsigned int apic, unsigned int reg,
++			    unsigned int value)
+ {
+ 	struct io_apic __iomem *io_apic = io_apic_base(apic);
+ 	writel(reg, &io_apic->index);
+@@ -334,7 +372,8 @@ static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned i
+  *
+  * Older SiS APIC requires we rewrite the index register
+  */
+-static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value)
++static void __io_apic_modify(unsigned int apic, unsigned int reg,
++			     unsigned int value)
+ {
+ 	struct io_apic __iomem *io_apic = io_apic_base(apic);
+ 
+@@ -3873,6 +3912,11 @@ static struct resource * __init ioapic_setup_resources(int nr_ioapics)
+ 
+ void __init ioapic_and_gsi_init(void)
+ {
++	io_apic_ops.init();
++}
++
++static void __init __ioapic_init_mappings(void)
++{
+ 	unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0;
+ 	struct resource *ioapic_res;
+ 	int i;
+-- 
+1.7.7.5
+
diff --git a/x86-apic_ops-Replace-apic_ops-with-x86_apic_ops.patch b/x86-apic_ops-Replace-apic_ops-with-x86_apic_ops.patch
new file mode 100644
index 0000000..ddbb924
--- /dev/null
+++ b/x86-apic_ops-Replace-apic_ops-with-x86_apic_ops.patch
@@ -0,0 +1,258 @@
+. which makes the code fit within the rest of the x86_ops functions.
+
+Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
+[v1: Changed x86_apic -> x86_ioapic per Yinghai Lu <yinghai at kernel.org> suggestion]
+Acked-by: Suresh Siddha <suresh.b.siddha at intel.com>
+---
+ arch/x86/include/asm/io_apic.h  |   40 +++++++++++++++++++++--------
+ arch/x86/include/asm/x86_init.h |    8 ++++++
+ arch/x86/kernel/apic/io_apic.c  |   54 ++++----------------------------------
+ arch/x86/kernel/setup.c         |    2 +-
+ arch/x86/kernel/x86_init.c      |    8 ++++++
+ 5 files changed, 52 insertions(+), 60 deletions(-)
+
+diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
+index 190d8c2..ba1b11a 100644
+--- a/arch/x86/include/asm/io_apic.h
++++ b/arch/x86/include/asm/io_apic.h
+@@ -5,6 +5,7 @@
+ #include <asm/mpspec.h>
+ #include <asm/apicdef.h>
+ #include <asm/irq_vectors.h>
++#include <asm/x86_init.h>
+ 
+ /*
+  * Intel IO-APIC support for SMP and UP systems.
+@@ -21,15 +22,6 @@
+ #define IO_APIC_REDIR_LEVEL_TRIGGER	(1 << 15)
+ #define IO_APIC_REDIR_MASKED		(1 << 16)
+ 
+-struct io_apic_ops {
+-	void (*init)(void);
+-	unsigned int (*read)(unsigned int apic, unsigned int reg);
+-	void (*write)(unsigned int apic, unsigned int reg, unsigned int value);
+-	void (*modify)(unsigned int apic, unsigned int reg, unsigned int value);
+-};
+-
+-void __init set_io_apic_ops(const struct io_apic_ops *);
+-
+ /*
+  * The structure of the IO-APIC:
+  */
+@@ -156,7 +148,6 @@ struct io_apic_irq_attr;
+ extern int io_apic_set_pci_routing(struct device *dev, int irq,
+ 		 struct io_apic_irq_attr *irq_attr);
+ void setup_IO_APIC_irq_extra(u32 gsi);
+-extern void ioapic_and_gsi_init(void);
+ extern void ioapic_insert_resources(void);
+ 
+ int io_apic_setup_irq_pin_once(unsigned int irq, int node, struct io_apic_irq_attr *attr);
+@@ -185,12 +176,35 @@ extern void mp_save_irq(struct mpc_intsrc *m);
+ 
+ extern void disable_ioapic_support(void);
+ 
++
++void __init native_ioapic_init_mappings(void);
++unsigned int native_ioapic_read(unsigned int apic, unsigned int reg);
++void native_ioapic_write(unsigned int apic, unsigned int reg,
++			 unsigned int val);
++void native_ioapic_modify(unsigned int apic, unsigned int reg,
++			  unsigned int val);
++
++static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
++{
++	return x86_ioapic.read(apic, reg);
++}
++
++static inline void io_apic_write(unsigned int apic, unsigned int reg,
++				 unsigned int value)
++{
++	x86_ioapic.write(apic, reg, value);
++}
++
++static inline void io_apic_modify(unsigned int apic, unsigned int reg,
++				  unsigned int value)
++{
++	x86_ioapic.modify(apic, reg, value);
++}
+ #else  /* !CONFIG_X86_IO_APIC */
+ 
+ #define io_apic_assign_pci_irqs 0
+ #define setup_ioapic_ids_from_mpc x86_init_noop
+ static const int timer_through_8259 = 0;
+-static inline void ioapic_and_gsi_init(void) { }
+ static inline void ioapic_insert_resources(void) { }
+ #define gsi_top (NR_IRQS_LEGACY)
+ static inline int mp_find_ioapic(u32 gsi) { return 0; }
+@@ -212,6 +226,10 @@ static inline int restore_ioapic_entries(void)
+ 
+ static inline void mp_save_irq(struct mpc_intsrc *m) { };
+ static inline void disable_ioapic_support(void) { }
++#define native_ioapic_init_mappings NULL
++#define native_ioapic_read NULL
++#define native_ioapic_write NULL
++#define native_ioapic_modify NULL
+ #endif
+ 
+ #endif /* _ASM_X86_IO_APIC_H */
+diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
+index 517d476..a3730cc 100644
+--- a/arch/x86/include/asm/x86_init.h
++++ b/arch/x86/include/asm/x86_init.h
+@@ -182,10 +182,18 @@ struct x86_msi_ops {
+ 	void (*restore_msi_irqs)(struct pci_dev *dev, int irq);
+ };
+ 
++struct x86_ioapic_ops {
++	void (*init)(void);
++	unsigned int (*read)(unsigned int apic, unsigned int reg);
++	void (*write)(unsigned int apic, unsigned int reg, unsigned int value);
++	void (*modify)(unsigned int apic, unsigned int reg, unsigned int value);
++};
++
+ extern struct x86_init_ops x86_init;
+ extern struct x86_cpuinit_ops x86_cpuinit;
+ extern struct x86_platform_ops x86_platform;
+ extern struct x86_msi_ops x86_msi;
++extern struct x86_ioapic_ops x86_ioapic;
+ 
+ extern void x86_init_noop(void);
+ extern void x86_init_uint_noop(unsigned int unused);
+diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
+index bf120234..9a15d4b 100644
+--- a/arch/x86/kernel/apic/io_apic.c
++++ b/arch/x86/kernel/apic/io_apic.c
+@@ -67,25 +67,6 @@
+ #define for_each_irq_pin(entry, head) \
+ 	for (entry = head; entry; entry = entry->next)
+ 
+-static void __init __ioapic_init_mappings(void);
+-static unsigned int __io_apic_read(unsigned int apic, unsigned int reg);
+-static void __io_apic_write(unsigned int apic, unsigned int reg,
+-			    unsigned int val);
+-static void __io_apic_modify(unsigned int apic, unsigned int reg,
+-			     unsigned int val);
+-
+-static struct io_apic_ops io_apic_ops = {
+-	.init = __ioapic_init_mappings,
+-	.read = __io_apic_read,
+-	.write = __io_apic_write,
+-	.modify = __io_apic_modify,
+-};
+-
+-void __init set_io_apic_ops(const struct io_apic_ops *ops)
+-{
+-	io_apic_ops = *ops;
+-}
+-
+ /*
+  *      Is the SiS APIC rmw bug present ?
+  *      -1 = don't know, 0 = no, 1 = yes
+@@ -313,24 +294,6 @@ static void free_irq_at(unsigned int at, struct irq_cfg *cfg)
+ 	irq_free_desc(at);
+ }
+ 
+-static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
+-{
+-	return io_apic_ops.read(apic, reg);
+-}
+-
+-static inline void io_apic_write(unsigned int apic, unsigned int reg,
+-				 unsigned int value)
+-{
+-	io_apic_ops.write(apic, reg, value);
+-}
+-
+-static inline void io_apic_modify(unsigned int apic, unsigned int reg,
+-				  unsigned int value)
+-{
+-	io_apic_ops.modify(apic, reg, value);
+-}
+-
+-
+ struct io_apic {
+ 	unsigned int index;
+ 	unsigned int unused[3];
+@@ -351,15 +314,15 @@ static inline void io_apic_eoi(unsigned int apic, unsigned int vector)
+ 	writel(vector, &io_apic->eoi);
+ }
+ 
+-static unsigned int __io_apic_read(unsigned int apic, unsigned int reg)
++unsigned int native_ioapic_read(unsigned int apic, unsigned int reg)
+ {
+ 	struct io_apic __iomem *io_apic = io_apic_base(apic);
+ 	writel(reg, &io_apic->index);
+ 	return readl(&io_apic->data);
+ }
+ 
+-static void __io_apic_write(unsigned int apic, unsigned int reg,
+-			    unsigned int value)
++void native_ioapic_write(unsigned int apic, unsigned int reg,
++			 unsigned int value)
+ {
+ 	struct io_apic __iomem *io_apic = io_apic_base(apic);
+ 	writel(reg, &io_apic->index);
+@@ -372,8 +335,8 @@ static void __io_apic_write(unsigned int apic, unsigned int reg,
+  *
+  * Older SiS APIC requires we rewrite the index register
+  */
+-static void __io_apic_modify(unsigned int apic, unsigned int reg,
+-			     unsigned int value)
++void native_ioapic_modify(unsigned int apic, unsigned int reg,
++			  unsigned int value)
+ {
+ 	struct io_apic __iomem *io_apic = io_apic_base(apic);
+ 
+@@ -3910,12 +3873,7 @@ static struct resource * __init ioapic_setup_resources(int nr_ioapics)
+ 	return res;
+ }
+ 
+-void __init ioapic_and_gsi_init(void)
+-{
+-	io_apic_ops.init();
+-}
+-
+-static void __init __ioapic_init_mappings(void)
++void __init native_ioapic_init_mappings(void)
+ {
+ 	unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0;
+ 	struct resource *ioapic_res;
+diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
+index d7d5099..7eaef1a 100644
+--- a/arch/x86/kernel/setup.c
++++ b/arch/x86/kernel/setup.c
+@@ -1016,7 +1016,7 @@ void __init setup_arch(char **cmdline_p)
+ 	init_cpu_to_node();
+ 
+ 	init_apic_mappings();
+-	ioapic_and_gsi_init();
++	x86_ioapic.init();
+ 
+ 	kvm_guest_init();
+ 
+diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
+index 947a06c..df870d3 100644
+--- a/arch/x86/kernel/x86_init.c
++++ b/arch/x86/kernel/x86_init.c
+@@ -18,6 +18,7 @@
+ #include <asm/e820.h>
+ #include <asm/time.h>
+ #include <asm/irq.h>
++#include <asm/io_apic.h>
+ #include <asm/pat.h>
+ #include <asm/tsc.h>
+ #include <asm/iommu.h>
+@@ -117,3 +118,10 @@ struct x86_msi_ops x86_msi = {
+ 	.teardown_msi_irqs = default_teardown_msi_irqs,
+ 	.restore_msi_irqs = default_restore_msi_irqs,
+ };
++
++struct x86_ioapic_ops x86_ioapic = {
++	.init = native_ioapic_init_mappings,
++	.read = native_ioapic_read,
++	.write = native_ioapic_write,
++	.modify = native_ioapic_modify,
++};
+-- 
+1.7.7.5
+
diff --git a/x86-ioapic-add-register-checks-for-bogus-io-apic-entries.patch b/x86-ioapic-add-register-checks-for-bogus-io-apic-entries.patch
new file mode 100644
index 0000000..9928829
--- /dev/null
+++ b/x86-ioapic-add-register-checks-for-bogus-io-apic-entries.patch
@@ -0,0 +1,93 @@
+On Tue, 2012-01-31 at 09:26 -0500, Josh Boyer wrote:
+> On Wed, Jan 25, 2012 at 06:15:35PM -0500, Josh Boyer wrote:
+> > On Wed, Jan 25, 2012 at 02:04:08PM -0800, Suresh Siddha wrote:
+> > > On Wed, 2012-01-25 at 08:49 -0500, Josh Boyer wrote:
+> > > > [    0.000000] IOAPIC[1]: apic_id 2, version 255, address 0xfec28000, GSI 24-279
+> > > 
+> > > This looks indeed like a bogus entry probably returning all 1's for
+> > > RTE's etc. Can you please send me a dmesg with "apic=verbose" boot
+> > > parameter?
+> > 
+> > Here you go:
+> > 
+> > https://bugzilla.redhat.com/attachment.cgi?id=557552
+> 
+> Was this helpful at all?  I've been watching lkml for a related patch
+> in case I was missed on CC but haven't seen anything as of yet.
+
+Yes, it was helpful. Something like the appended patch should ignore the
+bogus io-apic entry all together. As I can't test this, can you or the
+reporter give the appended patch a try and ack please?
+
+thanks,
+suresh
+---
+
+From: Suresh Siddha <suresh.b.siddha at intel.com>
+Subject: x86, ioapic: add register checks for bogus io-apic entries
+
+With the recent changes to clear_IO_APIC_pin() which tries to clear
+remoteIRR bit explicitly, some of the users started to see
+"Unable to reset IRR for apic .." messages.
+
+Close look shows that these are related to bogus IO-APIC entries which
+return's all 1's for their io-apic registers. And the above mentioned error
+messages are benign. But kernel should have ignored such io-apic's in the
+first place.
+
+Check if register 0, 1, 2 of the listed io-apic are all 1's and ignore
+such io-apic.
+
+Reported-by: Álvaro Castillo <midgoon at gmail.com>
+Signed-off-by: Suresh Siddha <suresh.b.siddha at intel.com>
+---
+ arch/x86/kernel/apic/io_apic.c |   26 ++++++++++++++++++++++++++
+ 1 files changed, 26 insertions(+), 0 deletions(-)
+
+diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
+index fb07275..953e54d 100644
+--- a/arch/x86/kernel/apic/io_apic.c
++++ b/arch/x86/kernel/apic/io_apic.c
+@@ -3979,6 +3979,26 @@ static __init int bad_ioapic(unsigned long address)
+ 	return 0;
+ }
+ 
++static __init int bad_ioapic_regs(int idx)
++{
++	union IO_APIC_reg_00 reg_00;
++	union IO_APIC_reg_01 reg_01;
++	union IO_APIC_reg_02 reg_02;
++
++	reg_00.raw = io_apic_read(idx, 0);
++	reg_01.raw = io_apic_read(idx, 1);
++	reg_02.raw = io_apic_read(idx, 2);
++
++	if (reg_00.raw == -1 && reg_01.raw == -1 && reg_02.raw == -1) {
++		printk(KERN_WARNING
++		       "I/O APIC 0x%x regs return all ones, skipping!\n",
++		       mpc_ioapic_addr(idx));
++		return 1;
++	}
++
++	return 0;
++}
++
+ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
+ {
+ 	int idx = 0;
+@@ -3995,6 +4015,12 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
+ 	ioapics[idx].mp_config.apicaddr = address;
+ 
+ 	set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
++
++	if (bad_ioapic_regs(idx)) {
++		clear_fixmap(FIX_IO_APIC_BASE_0 + idx);
++		return;
++	}
++
+ 	ioapics[idx].mp_config.apicid = io_apic_unique_id(id);
+ 	ioapics[idx].mp_config.apicver = io_apic_get_version(idx);
+ 
+
+
+
diff --git a/xen-x86-Implement-x86_apic_ops.patch b/xen-x86-Implement-x86_apic_ops.patch
new file mode 100644
index 0000000..0963ecb
--- /dev/null
+++ b/xen-x86-Implement-x86_apic_ops.patch
@@ -0,0 +1,85 @@
+Or rather just implement one different function as opposed
+to the native one : the read function.
+
+We synthesize the values.
+
+Acked-by:  Suresh Siddha <suresh.b.siddha at intel.com>
+Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk at oracle.com>
+---
+ arch/x86/xen/Makefile    |    2 +-
+ arch/x86/xen/apic.c      |   17 +++++++++++++++++
+ arch/x86/xen/enlighten.c |    2 ++
+ arch/x86/xen/xen-ops.h   |    4 ++++
+ 4 files changed, 24 insertions(+), 1 deletions(-)
+ create mode 100644 arch/x86/xen/apic.c
+
+diff --git a/arch/x86/xen/Makefile b/arch/x86/xen/Makefile
+index add2c2d..96ab2c0 100644
+--- a/arch/x86/xen/Makefile
++++ b/arch/x86/xen/Makefile
+@@ -20,5 +20,5 @@ obj-$(CONFIG_EVENT_TRACING) += trace.o
+ obj-$(CONFIG_SMP)		+= smp.o
+ obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o
+ obj-$(CONFIG_XEN_DEBUG_FS)	+= debugfs.o
+-obj-$(CONFIG_XEN_DOM0)		+= vga.o
++obj-$(CONFIG_XEN_DOM0)		+= apic.o vga.o
+ obj-$(CONFIG_SWIOTLB_XEN)	+= pci-swiotlb-xen.o
+diff --git a/arch/x86/xen/apic.c b/arch/x86/xen/apic.c
+new file mode 100644
+index 0000000..71ed91c
+--- /dev/null
++++ b/arch/x86/xen/apic.c
+@@ -0,0 +1,17 @@
++#include <linux/init.h>
++#include <asm/x86_init.h>
++
++unsigned int xen_io_apic_read(unsigned apic, unsigned reg)
++{
++	if (reg == 0x1)
++		return 0x00170020;
++	else if (reg == 0x0)
++		return apic << 24;
++
++	return 0xff;
++}
++
++void __init xen_init_apic(void)
++{
++	x86_ioapic.read = xen_io_apic_read;
++}
+diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
+index 0732326..93a03195 100644
+--- a/arch/x86/xen/enlighten.c
++++ b/arch/x86/xen/enlighten.c
+@@ -1377,6 +1377,8 @@ asmlinkage void __init xen_start_kernel(void)
+ 		xen_start_info->console.domU.mfn = 0;
+ 		xen_start_info->console.domU.evtchn = 0;
+ 
++		xen_init_apic();
++
+ 		/* Make sure ACS will be enabled */
+ 		pci_request_acs();
+ 
+diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
+index b095739..45c0c06 100644
+--- a/arch/x86/xen/xen-ops.h
++++ b/arch/x86/xen/xen-ops.h
+@@ -92,11 +92,15 @@ struct dom0_vga_console_info;
+ 
+ #ifdef CONFIG_XEN_DOM0
+ void __init xen_init_vga(const struct dom0_vga_console_info *, size_t size);
++void __init xen_init_apic(void);
+ #else
+ static inline void __init xen_init_vga(const struct dom0_vga_console_info *info,
+ 				       size_t size)
+ {
+ }
++static inline void __init xen_init_apic(void)
++{
++}
+ #endif
+ 
+ /* Declare an asm function, along with symbols needed to make it
+-- 
+1.7.7.5
+


More information about the scm-commits mailing list