[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] xen/apic: Provide an 'apic_xen' to set the override the apic->[read|write] for all cases.



On Thu, Mar 17, 2011 at 12:41:43PM -0400, Konrad Rzeszutek Wilk wrote:
> On Thu, Mar 17, 2011 at 04:12:48PM +0000, Jan Beulich wrote:
> > >>> On 17.03.11 at 16:52, Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx> 
> > >>> wrote:
> > > 2.6.38 fixes this by allowing in acpi_register_lapic_address, the
> > > the set_fixmap_nocache(FIX_APIC_BASE, address) to be called and we
> > > can provide it with a dummy page and native_apic_read can happily
> > > read from that fake page.
> > 
> > I wonder whether that's going to be appropriate in cases...
> 
> If you boot the 2.6.38 it works, but it does provide these ugly and untrue 
> values:
> 
>    0.000000] ACPI: IOAPIC (id[0x0f] address[0xfec00000] gsi_base[0])
> [    0.000000] IOAPIC[0]: apic_id 15, version 255, address 0xfec00000, GSI 
> 0-255
> [    0.000000] ACPI: IOAPIC (id[0x0e] address[0xfec01000] gsi_base[36])
> [    0.000000] IOAPIC[1]: apic_id 14, version 255, address 0xfec01000, GSI 
> 36-291
> [    0.000000] ACPI: INT_SRC_OVR (bus 0 bus_irq 0 global_irq 2 dfl dfl)
> [    0.000000] Int: type 0, pol 0, trig 0, bus 00, IRQ 00, APIC ID f, APIC 
> INT 02
> [    0.000000] ACPI: INT_SRC_OVR (bus 0 bus_irq 8 global_irq 8 low edge)
> [    0.000000] Int: type 0, pol 3, trig 1, bus 00, IRQ 08, APIC ID f, APIC 
> INT 08
> [    0.000000] ACPI: INT_SRC_OVR (bus 0 bus_irq 14 global_irq 14 low edge)
> [    0.000000] Int: type 0, pol 3, trig 1, bus 00, IRQ 0e, APIC ID f, APIC 
> INT 0e
> [    0.000000] Int: type 0, pol 3, trig 3, bus 00, IRQ 09, APIC ID f, APIC 
> INT 09
> [    0.000000] ACPI: IRQ0 used by override.
> 
> I don't remember if it was suggested to hpa/ingo/tglx whether we could
> provide another 'struct apic' that would be Xen specific and the apic->probe()
> would either provide a struct mostly filled with dummy functions that return
> nothing, or the Xen apic->probe() function would over-write the current
> 'apic->read,write, etc' with the xen dummy functions.
> 
> However we seem to achieve this already by providing a dummy page that 
> is read/writen to by the native_apic_[read|write].

Except that mechanism seems to require some other back-ports from 2.6.38 that
I am not so sure about. The patch worked great on the IBM box but broke all
other ones. Stefano had sent me a couple of fixes where we remove some other
"if (xen_initial_domain)" and move the "memset(ioapic_dummy_.." to another
location but it did not work completly right.

Instead of chasing the right combination, I went ahead with what
I suggested about introducing another 'struct apic'.

Here is the patch and if I revert the fix that I posted and apply this one
(already on for-2.6.32/bug-fixes) I get all my machines to boot.

This is for 2.6.32 - don't know if we need to provide it for 2.6.38.

>From a92e580fbb1ddae8aafed6360a105f274348d776 Mon Sep 17 00:00:00 2001
From: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>
Date: Thu, 17 Mar 2011 14:17:52 -0400
Subject: [PATCH] xen/apic: Provide an 'apic_xen' to set the override the 
apic->[read|write] for all cases.

When we bootup we call 'set_xen_basic_apic_ops' which
sets apic->read to xen_apic_read. The default 'apic' is set to
apic_flat, so in essence we change apic_flat->read from native_apic_read
to xen_apic_read.

During bootup, the default_acpi_madt_oem_check is run which
runs through all of the apic_probe[] array, on which the last
one is is apic_physflat. And apic_physflat->probe() returns true
on this IBM Summit box (and ES7000 boxs, and whatever has FADT
set to ACPI_FADT_APIC_PHYSICAL) so we set apic now to apic_physflat
and the apic->read ends up being native_apic_read.

2.6.38 fixes this by allowing in acpi_register_lapic_address, the
the set_fixmap_nocache(FIX_APIC_BASE, address) to be called and we
can provide it with a dummy page and native_apic_read can happily
read from that fake page.

However, the 2.6.38 is not that applicable here as it crashes
the case for non-IBM machines. The patch:
"xen/ioapic: Allow set_fixmap to set FIX_APIC_BASE to dummy mapping."
(7cb068cf1ba90425e12f3a7b3caed9d018fa9b8c) tried this and while it
worked for IBM Summit machines it broke all other. Moving the
memset to other areas of the code did not help either. The author
thinks that there must be some extra back-ports involved to use that
mechanism.

This fix adds a 'struct apic' that is Xen specific. This 'apic_xen'
is the first item on the apic_probe[i] for both 32 and 64-bit systems.
As the the first on the list, if it detects that it is running under Xen
it will short-circuit the iteration through the apic_probe[] hence not
allowing us to set it to apic_flat (or bigsmp on 32). We populate the
'apic_xen' with the default values from the 'apic' and set the members
with the Xen specific functions.

Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>
---
 arch/x86/kernel/apic/probe_32.c |    4 ++++
 arch/x86/kernel/apic/probe_64.c |    4 ++++
 arch/x86/xen/enlighten.c        |   26 ++++++++++++++++++++++++++
 3 files changed, 34 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c
index 88b9d22..798904d 100644
--- a/arch/x86/kernel/apic/probe_32.c
+++ b/arch/x86/kernel/apic/probe_32.c
@@ -174,11 +174,15 @@ extern struct apic apic_summit;
 extern struct apic apic_bigsmp;
 extern struct apic apic_es7000;
 extern struct apic apic_es7000_cluster;
+extern struct apic apic_xen;
 
 struct apic *apic = &apic_default;
 EXPORT_SYMBOL_GPL(apic);
 
 static struct apic *apic_probe[] __initdata = {
+#ifdef CONFIG_XEN
+       &apic_xen,
+#endif
 #ifdef CONFIG_X86_NUMAQ
        &apic_numaq,
 #endif
diff --git a/arch/x86/kernel/apic/probe_64.c b/arch/x86/kernel/apic/probe_64.c
index 4c56f54..5ab12a4 100644
--- a/arch/x86/kernel/apic/probe_64.c
+++ b/arch/x86/kernel/apic/probe_64.c
@@ -28,11 +28,15 @@ extern struct apic apic_physflat;
 extern struct apic apic_x2xpic_uv_x;
 extern struct apic apic_x2apic_phys;
 extern struct apic apic_x2apic_cluster;
+extern struct apic apic_xen;
 
 struct apic __read_mostly *apic = &apic_flat;
 EXPORT_SYMBOL_GPL(apic);
 
 static struct apic *apic_probe[] __initdata = {
+#ifdef CONFIG_XEN
+       &apic_xen,
+#endif
 #ifdef CONFIG_X86_UV
        &apic_x2apic_uv_x,
 #endif
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 070f138..c809938 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -750,6 +750,27 @@ static u32 xen_safe_apic_wait_icr_idle(void)
         return 0;
 }
 
+static __init int xen_safe_flat_acpi_madt_oem_check(char *oem_id,
+                                                   char *oem_table_id)
+{
+       if (!xen_initial_domain())
+               return 0;
+
+       return 1;
+}
+
+static __init int xen_safe_probe(void) {
+
+       if (!xen_initial_domain())
+               return 0;
+
+       return 1;
+}
+
+struct apic apic_xen = {
+       .name   = "xen",
+};
+
 static __init void set_xen_basic_apic_ops(void)
 {
        apic->read = xen_apic_read;
@@ -758,6 +779,11 @@ static __init void set_xen_basic_apic_ops(void)
        apic->icr_write = xen_apic_icr_write;
        apic->wait_icr_idle = xen_apic_wait_icr_idle;
        apic->safe_wait_icr_idle = xen_safe_apic_wait_icr_idle;
+       apic->probe = xen_safe_probe;
+       apic->acpi_madt_oem_check  = xen_safe_flat_acpi_madt_oem_check;
+       /* Copy over the full contents of the newly modified apic into
+        * our apic_xen, which is to be called first by apic_probe[]. */
+       memcpy(&apic_xen, apic, sizeof(struct apic));
 }
 
 #endif
-- 
1.7.1

> _______________________________________________
> Xen-devel mailing list
> Xen-devel@xxxxxxxxxxxxxxxxxxx
> http://lists.xensource.com/xen-devel

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.