set_irq_chained_handler(cascade, pseries_8259_cascade);
 }
 
+static struct device_node *cpuid_to_of_node(int cpu)
+{
+       struct device_node *np;
+       u32 hcpuid = get_hard_smp_processor_id(cpu);
+
+       for_each_node_by_type(np, "cpu") {
+               int i, len;
+               const u32 *intserv;
+
+               intserv = get_property(np, "ibm,ppc-interrupt-server#s", &len);
+
+               if (!intserv)
+                       intserv = get_property(np, "reg", &len);
+
+               i = len / sizeof(u32);
+
+               while (i--)
+                       if (intserv[i] == hcpuid)
+                               return np;
+       }
+
+       return NULL;
+}
+
 void __init xics_init_IRQ(void)
 {
-       int i;
+       int i, j;
        struct device_node *np;
        u32 ilen, indx = 0;
-       const u32 *ireg;
+       const u32 *ireg, *isize;
        int found = 0;
+       u32 hcpuid;
 
        ppc64_boot_msg(0x20, "XICS Init");
 
        xics_init_host();
 
        /* Find the server numbers for the boot cpu. */
-       for (np = of_find_node_by_type(NULL, "cpu");
-            np;
-            np = of_find_node_by_type(np, "cpu")) {
-               ireg = get_property(np, "reg", &ilen);
-               if (ireg && ireg[0] == get_hard_smp_processor_id(boot_cpuid)) {
-                       ireg = get_property(np,
-                                       "ibm,ppc-interrupt-gserver#s", &ilen);
-                       i = ilen / sizeof(int);
-                       if (ireg && i > 0) {
-                               default_server = ireg[0];
-                               /* take last element */
-                               default_distrib_server = ireg[i-1];
-                       }
-                       ireg = get_property(np,
+       np = cpuid_to_of_node(boot_cpuid);
+       BUG_ON(!np);
+       ireg = get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen);
+       if (!ireg)
+               goto skip_gserver_check;
+       i = ilen / sizeof(int);
+       hcpuid = get_hard_smp_processor_id(boot_cpuid);
+
+       /* Global interrupt distribution server is specified in the last
+        * entry of "ibm,ppc-interrupt-gserver#s" property. Get the last
+        * entry fom this property for current boot cpu id and use it as
+        * default distribution server
+        */
+       for (j = 0; j < i; j += 2) {
+               if (ireg[j] == hcpuid) {
+                       default_server = hcpuid;
+                       default_distrib_server = ireg[j+1];
+
+                       isize = get_property(np,
                                        "ibm,interrupt-server#-size", NULL);
-                       if (ireg)
-                               interrupt_server_size = *ireg;
-                       break;
+                       if (isize)
+                               interrupt_server_size = *isize;
                }
        }
+skip_gserver_check:
        of_node_put(np);
 
        if (firmware_has_feature(FW_FEATURE_LPAR))