]> git.ipfire.org Git - ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.39/patches.arch/x2APIC_PATCH_34_of_41_1b9b89e7f163336ad84200b66a17284dbf26aced
Imported linux-2.6.27.39 suse/xen patches.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.arch / x2APIC_PATCH_34_of_41_1b9b89e7f163336ad84200b66a17284dbf26aced
diff --git a/src/patches/suse-2.6.27.39/patches.arch/x2APIC_PATCH_34_of_41_1b9b89e7f163336ad84200b66a17284dbf26aced b/src/patches/suse-2.6.27.39/patches.arch/x2APIC_PATCH_34_of_41_1b9b89e7f163336ad84200b66a17284dbf26aced
new file mode 100644 (file)
index 0000000..d4c54ac
--- /dev/null
@@ -0,0 +1,365 @@
+From: Yinghai Lu <yhlu.kernel@gmail.com>
+Subject: x86: add apic probe for genapic 64bit, v2
+References: fate #303948 and fate #303984
+Patch-Mainline: queued for .28
+Commit-ID: 1b9b89e7f163336ad84200b66a17284dbf26aced
+
+Signed-off-by: Thomas Renninger <trenn@suse.de>
+
+introducing an APIC handling probing abstraction:
+
+ static struct genapic *apic_probe[] __initdata = {
+       &apic_x2apic_uv_x,
+       &apic_x2apic_phys,
+       &apic_x2apic_cluster,
+       &apic_physflat,
+       NULL,
+ };
+
+This way we can remove UV, x2apic specific code from genapic_64.c and
+move them to their specific genapic files.
+
+[ v2: fix compiling when CONFIG_ACPI is not set ]
+
+Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
+Cc: Jack Steiner <steiner@sgi.com>
+Cc: Suresh Siddha <suresh.b.siddha@intel.com>
+Signed-off-by: Ingo Molnar <mingo@elte.hu>
+
+---
+ arch/x86/kernel/genapic_64.c        |   86 ++++++++++--------------------------
+ arch/x86/kernel/genapic_flat_64.c   |   26 ++++++++++
+ arch/x86/kernel/genx2apic_cluster.c |   11 ++++
+ arch/x86/kernel/genx2apic_phys.c    |   21 ++++++++
+ arch/x86/kernel/genx2apic_uv_x.c    |   33 +++++++++++++
+ include/asm-x86/genapic_64.h        |    1 
+ 6 files changed, 117 insertions(+), 61 deletions(-)
+
+Index: linux-2.6.26/arch/x86/kernel/genapic_64.c
+===================================================================
+--- linux-2.6.26.orig/arch/x86/kernel/genapic_64.c
++++ linux-2.6.26/arch/x86/kernel/genapic_64.c
+@@ -16,62 +16,37 @@
+ #include <linux/ctype.h>
+ #include <linux/init.h>
+ #include <linux/hardirq.h>
+-#include <linux/dmar.h>
+ #include <asm/smp.h>
+ #include <asm/ipi.h>
+ #include <asm/genapic.h>
+-#ifdef CONFIG_ACPI
+-#include <acpi/acpi_bus.h>
+-#endif
+-
+-DEFINE_PER_CPU(int, x2apic_extra_bits);
++extern struct genapic apic_flat;
++extern struct genapic apic_physflat;
++extern struct genapic apic_x2xpic_uv_x;
++extern struct genapic apic_x2apic_phys;
++extern struct genapic apic_x2apic_cluster;
+ struct genapic __read_mostly *genapic = &apic_flat;
+-static int x2apic_phys = 0;
+-
+-static int set_x2apic_phys_mode(char *arg)
+-{
+-      x2apic_phys = 1;
+-      return 0;
+-}
+-early_param("x2apic_phys", set_x2apic_phys_mode);
+-
+-static enum uv_system_type uv_system_type;
++static struct genapic *apic_probe[] __initdata = {
++      &apic_x2apic_uv_x,
++      &apic_x2apic_phys,
++      &apic_x2apic_cluster,
++      &apic_physflat,
++      NULL,
++};
+ /*
+  * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode.
+  */
+ void __init setup_apic_routing(void)
+ {
+-      if (uv_system_type == UV_NON_UNIQUE_APIC)
+-              genapic = &apic_x2apic_uv_x;
+-      else if (cpu_has_x2apic && intr_remapping_enabled) {
+-              if (x2apic_phys)
+-                      genapic = &apic_x2apic_phys;
+-              else
+-                      genapic = &apic_x2apic_cluster;
+-      } else
+-#ifdef CONFIG_ACPI
+-      /*
+-       * Quirk: some x86_64 machines can only use physical APIC mode
+-       * regardless of how many processors are present (x86_64 ES7000
+-       * is an example).
+-       */
+-      if (acpi_gbl_FADT.header.revision > FADT2_REVISION_ID &&
+-                      (acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL))
+-              genapic = &apic_physflat;
+-      else
+-#endif
+-
+-      if (max_physical_apicid < 8)
+-              genapic = &apic_flat;
+-      else
+-              genapic = &apic_physflat;
+-
+-      printk(KERN_INFO "Setting APIC routing to %s\n", genapic->name);
++      if (genapic == &apic_flat) {
++              if (max_physical_apicid >= 8)
++                      genapic = &apic_physflat;
++              printk(KERN_INFO "Setting APIC routing to %s\n", genapic->name);
++      }
+ }
+ /* Same for both flat and physical. */
+@@ -83,24 +58,15 @@ void apic_send_IPI_self(int vector)
+ int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+ {
+-      if (!strcmp(oem_id, "SGI")) {
+-              if (!strcmp(oem_table_id, "UVL"))
+-                      uv_system_type = UV_LEGACY_APIC;
+-              else if (!strcmp(oem_table_id, "UVX"))
+-                      uv_system_type = UV_X2APIC;
+-              else if (!strcmp(oem_table_id, "UVH"))
+-                      uv_system_type = UV_NON_UNIQUE_APIC;
++      int i;
++
++      for (i = 0; apic_probe[i]; ++i) {
++              if (apic_probe[i]->acpi_madt_oem_check(oem_id, oem_table_id)) {
++                      genapic = apic_probe[i];
++                      printk(KERN_INFO "Setting APIC routing to %s.\n",
++                              genapic->name);
++                      return 1;
++              }
+       }
+       return 0;
+ }
+-
+-enum uv_system_type get_uv_system_type(void)
+-{
+-      return uv_system_type;
+-}
+-
+-int is_uv_system(void)
+-{
+-      return uv_system_type != UV_NONE;
+-}
+-EXPORT_SYMBOL_GPL(is_uv_system);
+Index: linux-2.6.26/arch/x86/kernel/genapic_flat_64.c
+===================================================================
+--- linux-2.6.26.orig/arch/x86/kernel/genapic_flat_64.c
++++ linux-2.6.26/arch/x86/kernel/genapic_flat_64.c
+@@ -21,6 +21,15 @@
+ #include <asm/genapic.h>
+ #include <mach_apicdef.h>
++#ifdef CONFIG_ACPI
++#include <acpi/acpi_bus.h>
++#endif
++
++static int __init flat_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
++{
++      return 1;
++}
++
+ static cpumask_t flat_target_cpus(void)
+ {
+       return cpu_online_map;
+@@ -138,6 +147,7 @@ static unsigned int phys_pkg_id(int inde
+ struct genapic apic_flat =  {
+       .name = "flat",
++      .acpi_madt_oem_check = flat_acpi_madt_oem_check,
+       .int_delivery_mode = dest_LowestPrio,
+       .int_dest_mode = (APIC_DEST_LOGICAL != 0),
+       .target_cpus = flat_target_cpus,
+@@ -160,6 +170,21 @@ struct genapic apic_flat =  {
+  * We cannot use logical delivery in this case because the mask
+  * overflows, so use physical mode.
+  */
++static int __init physflat_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
++{
++#ifdef CONFIG_ACPI
++      /*
++       * Quirk: some x86_64 machines can only use physical APIC mode
++       * regardless of how many processors are present (x86_64 ES7000
++       * is an example).
++       */
++      if (acpi_gbl_FADT.header.revision > FADT2_REVISION_ID &&
++              (acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL))
++              return 1;
++#endif
++
++      return 0;
++}
+ static cpumask_t physflat_target_cpus(void)
+ {
+@@ -206,6 +231,7 @@ static unsigned int physflat_cpu_mask_to
+ struct genapic apic_physflat =  {
+       .name = "physical flat",
++      .acpi_madt_oem_check = physflat_acpi_madt_oem_check,
+       .int_delivery_mode = dest_Fixed,
+       .int_dest_mode = (APIC_DEST_PHYSICAL != 0),
+       .target_cpus = physflat_target_cpus,
+Index: linux-2.6.26/arch/x86/kernel/genx2apic_cluster.c
+===================================================================
+--- linux-2.6.26.orig/arch/x86/kernel/genx2apic_cluster.c
++++ linux-2.6.26/arch/x86/kernel/genx2apic_cluster.c
+@@ -4,12 +4,22 @@
+ #include <linux/kernel.h>
+ #include <linux/ctype.h>
+ #include <linux/init.h>
++#include <linux/dmar.h>
++
+ #include <asm/smp.h>
+ #include <asm/ipi.h>
+ #include <asm/genapic.h>
+ DEFINE_PER_CPU(u32, x86_cpu_to_logical_apicid);
++static int __init x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
++{
++      if (cpu_has_x2apic && intr_remapping_enabled)
++              return 1;
++
++      return 0;
++}
++
+ /* Start with all IRQs pointing to boot CPU.  IRQ balancing will shift them. */
+ static cpumask_t x2apic_target_cpus(void)
+@@ -135,6 +145,7 @@ static void init_x2apic_ldr(void)
+ struct genapic apic_x2apic_cluster = {
+       .name = "cluster x2apic",
++      .acpi_madt_oem_check = x2apic_acpi_madt_oem_check,
+       .int_delivery_mode = dest_LowestPrio,
+       .int_dest_mode = (APIC_DEST_LOGICAL != 0),
+       .target_cpus = x2apic_target_cpus,
+Index: linux-2.6.26/arch/x86/kernel/genx2apic_phys.c
+===================================================================
+--- linux-2.6.26.orig/arch/x86/kernel/genx2apic_phys.c
++++ linux-2.6.26/arch/x86/kernel/genx2apic_phys.c
+@@ -4,10 +4,30 @@
+ #include <linux/kernel.h>
+ #include <linux/ctype.h>
+ #include <linux/init.h>
++#include <linux/dmar.h>
++
+ #include <asm/smp.h>
+ #include <asm/ipi.h>
+ #include <asm/genapic.h>
++DEFINE_PER_CPU(int, x2apic_extra_bits);
++
++static int x2apic_phys;
++
++static int set_x2apic_phys_mode(char *arg)
++{
++      x2apic_phys = 1;
++      return 0;
++}
++early_param("x2apic_phys", set_x2apic_phys_mode);
++
++static int __init x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
++{
++      if (cpu_has_x2apic && intr_remapping_enabled && x2apic_phys)
++              return 1;
++
++      return 0;
++}
+ /* Start with all IRQs pointing to boot CPU.  IRQ balancing will shift them. */
+@@ -122,6 +142,7 @@ void init_x2apic_ldr(void)
+ struct genapic apic_x2apic_phys = {
+       .name = "physical x2apic",
++      .acpi_madt_oem_check = x2apic_acpi_madt_oem_check,
+       .int_delivery_mode = dest_Fixed,
+       .int_dest_mode = (APIC_DEST_PHYSICAL != 0),
+       .target_cpus = x2apic_target_cpus,
+Index: linux-2.6.26/arch/x86/kernel/genx2apic_uv_x.c
+===================================================================
+--- linux-2.6.26.orig/arch/x86/kernel/genx2apic_uv_x.c
++++ linux-2.6.26/arch/x86/kernel/genx2apic_uv_x.c
+@@ -27,6 +27,34 @@
+ #include <asm/uv/uv_hub.h>
+ #include <asm/uv/bios.h>
++static enum uv_system_type uv_system_type;
++
++static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
++{
++      if (!strcmp(oem_id, "SGI")) {
++              if (!strcmp(oem_table_id, "UVL"))
++                      uv_system_type = UV_LEGACY_APIC;
++              else if (!strcmp(oem_table_id, "UVX"))
++                      uv_system_type = UV_X2APIC;
++              else if (!strcmp(oem_table_id, "UVH")) {
++                      uv_system_type = UV_NON_UNIQUE_APIC;
++                      return 1;
++              }
++      }
++      return 0;
++}
++
++enum uv_system_type get_uv_system_type(void)
++{
++      return uv_system_type;
++}
++
++int is_uv_system(void)
++{
++      return uv_system_type != UV_NONE;
++}
++EXPORT_SYMBOL(is_uv_system);
++
+ DEFINE_PER_CPU(struct uv_hub_info_s, __uv_hub_info);
+ EXPORT_PER_CPU_SYMBOL_GPL(__uv_hub_info);
+@@ -153,7 +181,7 @@ static unsigned int get_apic_id(unsigned
+       return id;
+ }
+-static long set_apic_id(unsigned int id)
++static unsigned long set_apic_id(unsigned int id)
+ {
+       unsigned long x;
+@@ -182,6 +210,7 @@ static void uv_send_IPI_self(int vector)
+ struct genapic apic_x2apic_uv_x = {
+       .name = "UV large system",
++      .acpi_madt_oem_check = uv_acpi_madt_oem_check,
+       .int_delivery_mode = dest_Fixed,
+       .int_dest_mode = (APIC_DEST_PHYSICAL != 0),
+       .target_cpus = uv_target_cpus,
+@@ -435,3 +464,5 @@ void __cpuinit uv_cpu_init(void)
+       if (get_uv_system_type() == UV_NON_UNIQUE_APIC)
+               set_x2apic_extra_bits(uv_hub_info->pnode);
+ }
++
++
+Index: linux-2.6.26/include/asm-x86/genapic_64.h
+===================================================================
+--- linux-2.6.26.orig/include/asm-x86/genapic_64.h
++++ linux-2.6.26/include/asm-x86/genapic_64.h
+@@ -14,6 +14,7 @@
+ struct genapic {
+       char *name;
++      int (*acpi_madt_oem_check)(char *oem_id, char *oem_table_id);
+       u32 int_delivery_mode;
+       u32 int_dest_mode;
+       int (*apic_id_registered)(void);