[ppc46] SMT processor support and logical cpu numbering, from Dave Engebretsen And SMT processor support & move back to a logical cpu numbering in support of DLPAR work. --- arch/ppc64/kernel/idle.c | 0 arch/ppc64/kernel/open_pic.c | 31 ++++- arch/ppc64/kernel/prom.c | 228 +++++++++++++++++++++++++++++++++--------- arch/ppc64/kernel/setup.c | 24 +++- arch/ppc64/kernel/smp.c | 7 + arch/ppc64/kernel/xics.c | 10 - include/asm-ppc64/paca.h | 2 include/asm-ppc64/processor.h | 1 include/asm-ppc64/smp.h | 23 ++++ 9 files changed, 259 insertions(+), 67 deletions(-) diff -puN arch/ppc64/kernel/idle.c~ppc64-logical_cpu arch/ppc64/kernel/idle.c diff -puN arch/ppc64/kernel/open_pic.c~ppc64-logical_cpu arch/ppc64/kernel/open_pic.c --- 25/arch/ppc64/kernel/open_pic.c~ppc64-logical_cpu 2004-01-13 23:22:45.000000000 -0800 +++ 25-akpm/arch/ppc64/kernel/open_pic.c 2004-01-13 23:22:45.000000000 -0800 @@ -85,10 +85,10 @@ unsigned int openpic_vec_spurious; */ #ifdef CONFIG_SMP #define THIS_CPU Processor[cpu] -#define DECL_THIS_CPU int cpu = smp_processor_id() +#define DECL_THIS_CPU int cpu = hard_smp_processor_id() #define CHECK_THIS_CPU check_arg_cpu(cpu) #else -#define THIS_CPU Processor[smp_processor_id()] +#define THIS_CPU Processor[hard_smp_processor_id()] #define DECL_THIS_CPU #define CHECK_THIS_CPU #endif /* CONFIG_SMP */ @@ -355,7 +355,7 @@ void __init openpic_init(int main_pic, i /* SIOint (8259 cascade) is special */ if (offset) { openpic_initirq(0, 8, offset, 1, 1); - openpic_mapirq(0, 1 << boot_cpuid); + openpic_mapirq(0, 1 << get_hard_smp_processor_id(boot_cpuid)); } /* Init all external sources */ @@ -373,7 +373,7 @@ void __init openpic_init(int main_pic, i /* Enabled, Priority 8 or 9 */ openpic_initirq(i, pri, i+offset, !sense, sense); /* Processor 0 */ - openpic_mapirq(i, 1 << boot_cpuid); + openpic_mapirq(i, 1 << get_hard_smp_processor_id(boot_cpuid)); } /* Init descriptors */ @@ -514,10 +514,23 @@ static void openpic_set_spurious(u_int v vec); } +/* + * Convert a cpu mask from logical to physical cpu numbers. + */ +static inline u32 physmask(u32 cpumask) +{ + int i; + u32 mask = 0; + + for (i = 0; i < NR_CPUS; ++i, cpumask >>= 1) + mask |= (cpumask & 1) << get_hard_smp_processor_id(i); + return mask; +} + void openpic_init_processor(u_int cpumask) { openpic_write(&OpenPIC->Global.Processor_Initialization, - cpumask & cpus_coerce(cpu_online_map)); + physmask(cpumask & cpus_coerce(cpu_online_map))); } #ifdef CONFIG_SMP @@ -551,7 +564,7 @@ void openpic_cause_IPI(u_int ipi, u_int CHECK_THIS_CPU; check_arg_ipi(ipi); openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi), - cpumask & cpus_coerce(cpu_online_map)); + physmask(cpumask & cpus_coerce(cpu_online_map))); } void openpic_request_IPIs(void) @@ -592,7 +605,7 @@ void __devinit do_openpic_setup_cpu(void { #ifdef CONFIG_IRQ_ALL_CPUS int i; - u32 msk = 1 << smp_processor_id(); + u32 msk = 1 << hard_smp_processor_id(); #endif spin_lock(&openpic_setup_lock); @@ -637,7 +650,7 @@ static void __init openpic_maptimer(u_in { check_arg_timer(timer); openpic_write(&OpenPIC->Global.Timer[timer].Destination, - cpumask & cpus_coerce(cpu_online_map)); + physmask(cpumask & cpus_coerce(cpu_online_map))); } @@ -763,7 +776,7 @@ static void openpic_set_affinity(unsigne cpumask_t tmp; cpus_and(tmp, cpumask, cpu_online_map); - openpic_mapirq(irq_nr - open_pic_irq_offset, cpus_coerce(tmp)); + openpic_mapirq(irq_nr - open_pic_irq_offset, physmask(cpus_coerce(tmp))); } #ifdef CONFIG_SMP diff -puN arch/ppc64/kernel/prom.c~ppc64-logical_cpu arch/ppc64/kernel/prom.c --- 25/arch/ppc64/kernel/prom.c~ppc64-logical_cpu 2004-01-13 23:22:45.000000000 -0800 +++ 25-akpm/arch/ppc64/kernel/prom.c 2004-01-13 23:22:45.000000000 -0800 @@ -149,6 +149,7 @@ char *bootpath = 0; char *bootdevice = 0; int boot_cpuid = 0; +#define MAX_CPU_THREADS 2 struct device_node *allnodes = 0; /* use when traversing tree through the allnext, child, sibling, @@ -898,16 +899,21 @@ static void prom_hold_cpus(unsigned long mem) { unsigned long i; - unsigned int cpuid; + unsigned int reg; phandle node; unsigned long offset = reloc_offset(); char type[64], *path; + int cpuid = 0; + unsigned int interrupt_server[MAX_CPU_THREADS]; + unsigned int cpu_threads, hw_cpu_num; + int propsize; extern void __secondary_hold(void); extern unsigned long __secondary_hold_spinloop; extern unsigned long __secondary_hold_acknowledge; unsigned long *spinloop = __v2a(&__secondary_hold_spinloop); unsigned long *acknowledge = __v2a(&__secondary_hold_acknowledge); unsigned long secondary_hold = (unsigned long)__v2a(*PTRRELOC((unsigned long *)__secondary_hold)); + struct naca_struct *_naca = RELOC(naca); struct systemcfg *_systemcfg = RELOC(systemcfg); struct paca_struct *_xPaca = PTRRELOC(&paca[0]); struct prom_t *_prom = PTRRELOC(&prom); @@ -960,13 +966,9 @@ prom_hold_cpus(unsigned long mem) if (strcmp(type, RELOC("okay")) != 0) continue; - cpuid = -1; + reg = -1; call_prom(RELOC("getprop"), 4, 1, node, RELOC("reg"), - &cpuid, sizeof(cpuid)); - - /* Only need to start secondary procs, not ourself. */ - if ( cpuid == _prom->cpu ) - continue; + ®, sizeof(reg)); path = (char *) mem; memset(path, 0, 256); @@ -976,12 +978,14 @@ prom_hold_cpus(unsigned long mem) #ifdef DEBUG_PROM prom_print_nl(); - prom_print(RELOC("cpu hw idx = 0x")); + prom_print(RELOC("cpuid = 0x")); prom_print_hex(cpuid); prom_print_nl(); + prom_print(RELOC("cpu hw idx = 0x")); + prom_print_hex(reg); + prom_print_nl(); #endif - prom_print(RELOC("starting cpu ")); - prom_print(path); + _xPaca[cpuid].xHwProcNum = reg; /* Init the acknowledge var which will be reset by * the secondary cpu when it awakens from its OF @@ -989,45 +993,80 @@ prom_hold_cpus(unsigned long mem) */ *acknowledge = (unsigned long)-1; -#ifdef DEBUG_PROM - prom_print(RELOC(" 3) spinloop = 0x")); - prom_print_hex(spinloop); - prom_print_nl(); - prom_print(RELOC(" 3) *spinloop = 0x")); - prom_print_hex(*spinloop); - prom_print_nl(); - prom_print(RELOC(" 3) acknowledge = 0x")); - prom_print_hex(acknowledge); - prom_print_nl(); - prom_print(RELOC(" 3) *acknowledge = 0x")); - prom_print_hex(*acknowledge); - prom_print_nl(); - prom_print(RELOC(" 3) secondary_hold = 0x")); - prom_print_hex(secondary_hold); + propsize = call_prom(RELOC("getprop"), 4, 1, node, + RELOC("ibm,ppc-interrupt-server#s"), + &interrupt_server, + sizeof(interrupt_server)); + if (propsize < 0) { + /* no property. old hardware has no SMT */ + cpu_threads = 1; + interrupt_server[0] = reg; /* fake it with phys id */ + } else { + /* We have a threaded processor */ + cpu_threads = propsize / sizeof(u32); + if (cpu_threads > MAX_CPU_THREADS) { + prom_print(RELOC("SMT: too many threads!\nSMT: found ")); + prom_print_hex(cpu_threads); + prom_print(RELOC(", max is ")); + prom_print_hex(MAX_CPU_THREADS); prom_print_nl(); -#endif - call_prom(RELOC("start-cpu"), 3, 0, node, secondary_hold, cpuid); + cpu_threads = 1; /* ToDo: panic? */ + } + } + + hw_cpu_num = interrupt_server[0]; + if (hw_cpu_num != _prom->cpu) { + /* Primary Thread of non-boot cpu */ + prom_print_hex(cpuid); + prom_print(RELOC(" : starting cpu ")); + prom_print(path); prom_print(RELOC("...")); + call_prom(RELOC("start-cpu"), 3, 0, node, + secondary_hold, cpuid); + for ( i = 0 ; (i < 100000000) && (*acknowledge == ((unsigned long)-1)); i++ ) ; -#ifdef DEBUG_PROM - { - unsigned long *p = 0x0; - prom_print(RELOC(" 4) 0x0 = 0x")); - prom_print_hex(*p); - prom_print_nl(); - } -#endif + if (*acknowledge == cpuid) { prom_print(RELOC("ok\n")); /* Set the number of active processors. */ _systemcfg->processorCount++; - _xPaca[cpuid].active = 1; + cpu_set(cpuid, RELOC(cpu_available_map)); + cpu_set(cpuid, RELOC(cpu_possible_map)); + cpu_set(cpuid, RELOC(cpu_present_at_boot)); } else { prom_print(RELOC("failed: ")); prom_print_hex(*acknowledge); prom_print_nl(); + /* prom_panic(RELOC("cpu failed to start")); */ + } + } else { + prom_print_hex(cpuid); + prom_print(RELOC(" : booting cpu ")); + prom_print(path); + prom_print_nl(); + cpu_set(cpuid, RELOC(cpu_available_map)); + cpu_set(cpuid, RELOC(cpu_possible_map)); + cpu_set(cpuid, RELOC(cpu_online_map)); + cpu_set(cpuid, RELOC(cpu_present_at_boot)); + } + + /* Init paca for secondary threads. They start later. */ + for (i=1; i < cpu_threads; i++) { + cpuid++; + _xPaca[cpuid].xHwProcNum = interrupt_server[i]; + prom_print_hex(interrupt_server[i]); + prom_print(RELOC(" : preparing thread ... ")); + if (_naca->smt_state) { + cpu_set(cpuid, RELOC(cpu_available_map)); + cpu_set(cpuid, RELOC(cpu_present_at_boot)); + prom_print(RELOC("available")); + } else { + prom_print(RELOC("not available")); + } + prom_print_nl(); } + cpuid++; } #ifdef CONFIG_HMT /* Only enable HMT on processors that provide support. */ @@ -1037,10 +1076,10 @@ prom_hold_cpus(unsigned long mem) prom_print(RELOC(" starting secondary threads\n")); for (i = 0; i < NR_CPUS; i += 2) { - if (!_xPaca[i].active) + if (!cpu_online(i)) continue; - if (i == boot_cpuid) { + if (i == 0) { unsigned long pir = _get_PIR(); if (__is_processor(PV_PULSAR)) { RELOC(hmt_thread_data)[i].pir = @@ -1050,7 +1089,8 @@ prom_hold_cpus(unsigned long mem) pir & 0x3ff; } } - _xPaca[i+1].active = 1; +/* cpu_set(i+1, cpu_online_map); */ + cpu_set(i+1, RELOC(cpu_possible_map)); } _systemcfg->processorCount *= 2; } else { @@ -1063,6 +1103,105 @@ prom_hold_cpus(unsigned long mem) #endif } +static void +smt_setup(void) +{ + char *p, *q; + char my_smt_enabled = SMT_DYNAMIC; + unsigned long my_smt_snooze_delay; + ihandle prom_options = NULL; + char option[9]; + unsigned long offset = reloc_offset(); + struct naca_struct *_naca = RELOC(naca); + char found = 0; + + if (strstr(RELOC(cmd_line), RELOC("smt-enabled="))) { + for (q = RELOC(cmd_line); (p = strstr(q, RELOC("smt-enabled="))) != 0; ) { + q = p + 12; + if (p > RELOC(cmd_line) && p[-1] != ' ') + continue; + found = 1; + if (q[0] == 'o' && q[1] == 'f' && + q[2] == 'f' && (q[3] == ' ' || q[3] == '\0')) { + my_smt_enabled = SMT_OFF; + } else if (q[0]=='o' && q[1] == 'n' && + (q[2] == ' ' || q[2] == '\0')) { + my_smt_enabled = SMT_ON; + } else { + my_smt_enabled = SMT_DYNAMIC; + } + } + } + if (!found) { + prom_options = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/options")); + if (prom_options != (ihandle) -1) { + call_prom(RELOC("getprop"), + 4, 1, prom_options, + RELOC("ibm,smt-enabled"), + option, + sizeof(option)); + if (option[0] != 0) { + found = 1; + if (!strcmp(option, "off")) + my_smt_enabled = SMT_OFF; + else if (!strcmp(option, "on")) + my_smt_enabled = SMT_ON; + else + my_smt_enabled = SMT_DYNAMIC; + } + } + } + + if (!found ) + my_smt_enabled = SMT_DYNAMIC; /* default to on */ + + found = 0; + if (my_smt_enabled) { + if (strstr(RELOC(cmd_line), RELOC("smt-snooze-delay="))) { + for (q = RELOC(cmd_line); (p = strstr(q, RELOC("smt-snooze-delay="))) != 0; ) { + q = p + 17; + if (p > RELOC(cmd_line) && p[-1] != ' ') + continue; + found = 1; + /* Don't use simple_strtoul() because _ctype & others aren't RELOC'd */ + my_smt_snooze_delay = 0; + while (*q >= '0' && *q <= '9') { + my_smt_snooze_delay = my_smt_snooze_delay * 10 + *q - '0'; + q++; + } + } + } + + if (!found) { + prom_options = (ihandle)call_prom(RELOC("finddevice"), 1, 1, RELOC("/options")); + if (prom_options != (ihandle) -1) { + call_prom(RELOC("getprop"), + 4, 1, prom_options, + RELOC("ibm,smt-snooze-delay"), + option, + sizeof(option)); + if (option[0] != 0) { + found = 1; + /* Don't use simple_strtoul() because _ctype & others aren't RELOC'd */ + my_smt_snooze_delay = 0; + q = option; + while (*q >= '0' && *q <= '9') { + my_smt_snooze_delay = my_smt_snooze_delay * 10 + *q - '0'; + q++; + } + } + } + } + + if (!found) { + my_smt_snooze_delay = 30000; /* default value */ + } + } else { + my_smt_snooze_delay = 0; /* default value */ + } + _naca->smt_snooze_delay = my_smt_snooze_delay; + _naca->smt_state = my_smt_enabled; +} /* * We enter here early on, when the Open Firmware prom is still @@ -1145,11 +1284,9 @@ prom_init(unsigned long r3, unsigned lon cpu_pkg, RELOC("reg"), &getprop_rval, sizeof(getprop_rval)); _prom->cpu = (int)(unsigned long)getprop_rval; - _xPaca[_prom->cpu].active = 1; -#ifdef CONFIG_SMP - cpu_set(_prom->cpu, RELOC(cpu_online_map)); -#endif - RELOC(boot_cpuid) = _prom->cpu; + _xPaca[0].xHwProcNum = _prom->cpu; + + RELOC(boot_cpuid) = 0; #ifdef DEBUG_PROM prom_print(RELOC("Booting CPU hw index = 0x")); @@ -1183,11 +1320,12 @@ prom_init(unsigned long r3, unsigned lon /* Initialize some system info into the Naca early... */ mem = prom_initialize_naca(mem); + smt_setup(); + /* If we are on an SMP machine, then we *MUST* do the * following, regardless of whether we have an SMP * kernel or not. */ - if (_systemcfg->processorCount > 1) prom_hold_cpus(mem); #ifdef DEBUG_PROM diff -puN arch/ppc64/kernel/setup.c~ppc64-logical_cpu arch/ppc64/kernel/setup.c --- 25/arch/ppc64/kernel/setup.c~ppc64-logical_cpu 2004-01-13 23:22:45.000000000 -0800 +++ 25-akpm/arch/ppc64/kernel/setup.c 2004-01-13 23:22:45.000000000 -0800 @@ -58,6 +58,8 @@ extern void iSeries_init_early( void ); extern void pSeries_init_early( void ); extern void pSeriesLP_init_early(void); extern void mm_init_ppc64( void ); +extern void pseries_secondary_smp_init(unsigned long); +extern int idle_setup(void); extern void vpa_init(int cpu); unsigned long decr_overclock = 1; @@ -144,6 +146,8 @@ void __init disable_early_printk(void) void setup_system(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) { + unsigned int ret, i; + #ifdef CONFIG_XMON_DEFAULT debugger = xmon; debugger_bpt = xmon_bpt; @@ -187,6 +191,21 @@ void setup_system(unsigned long r3, unsi if (systemcfg->platform & PLATFORM_PSERIES) { early_console_initialized = 1; register_console(&udbg_console); + finish_device_tree(); + chrp_init(r3, r4, r5, r6, r7); + + /* Start secondary threads on SMT systems */ + for (i = 0; i < NR_CPUS; i++) { + if(cpu_available(i) && !cpu_possible(i)) { + printk("%16.16x : starting thread\n", i); + rtas_call(rtas_token("start-cpu"), 3, 1, + (void *)&ret, + get_hard_smp_processor_id(i), + *((unsigned long *)pseries_secondary_smp_init), i); + cpu_set(i, cpu_possible_map); + systemcfg->processorCount++; + } + } } printk("Starting Linux PPC64 %s\n", UTS_RELEASE); @@ -205,11 +224,6 @@ void setup_system(unsigned long r3, unsi printk("htab_data.num_ptegs = 0x%lx\n", htab_data.htab_num_ptegs); printk("-----------------------------------------------------\n"); - if (systemcfg->platform & PLATFORM_PSERIES) { - finish_device_tree(); - chrp_init(r3, r4, r5, r6, r7); - } - mm_init_ppc64(); if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) { diff -puN arch/ppc64/kernel/smp.c~ppc64-logical_cpu arch/ppc64/kernel/smp.c --- 25/arch/ppc64/kernel/smp.c~ppc64-logical_cpu 2004-01-13 23:22:45.000000000 -0800 +++ 25-akpm/arch/ppc64/kernel/smp.c 2004-01-13 23:22:45.000000000 -0800 @@ -53,8 +53,11 @@ int smp_threads_ready; unsigned long cache_decay_ticks; -/* initialised so it doesn't end up in bss */ +/* Initialised so it doesn't end up in bss */ +cpumask_t cpu_possible_map = CPU_MASK_NONE; cpumask_t cpu_online_map = CPU_MASK_NONE; +cpumask_t cpu_available_map = CPU_MASK_NONE; +cpumask_t cpu_present_at_boot = CPU_MASK_NONE; EXPORT_SYMBOL(cpu_online_map); @@ -67,6 +70,8 @@ extern unsigned char stab_array[]; extern int cpu_idle(void *unused); void smp_call_function_interrupt(void); void smp_message_pass(int target, int msg, unsigned long data, int wait); +extern long register_vpa(unsigned long flags, unsigned long proc, + unsigned long vpa); #define smp_message_pass(t,m,d,w) smp_ops->message_pass((t),(m),(d),(w)) diff -puN include/asm-ppc64/paca.h~ppc64-logical_cpu include/asm-ppc64/paca.h --- 25/include/asm-ppc64/paca.h~ppc64-logical_cpu 2004-01-13 23:22:45.000000000 -0800 +++ 25-akpm/include/asm-ppc64/paca.h 2004-01-13 23:22:45.000000000 -0800 @@ -61,7 +61,7 @@ struct paca_struct { struct ItLpRegSave *xLpRegSavePtr; /* Pointer to LpRegSave for PLIC 0x08 */ u64 xCurrent; /* Pointer to current 0x10 */ u16 xPacaIndex; /* Logical processor number 0x18 */ - u16 active; /* Is this cpu active? 0x1a */ + u16 xHwProcNum; /* Physical processor number 0x1A */ u32 default_decr; /* Default decrementer value 0x1c */ u64 unused1; u64 xKsave; /* Saved Kernel stack addr or zero 0x28 */ diff -puN include/asm-ppc64/smp.h~ppc64-logical_cpu include/asm-ppc64/smp.h --- 25/include/asm-ppc64/smp.h~ppc64-logical_cpu 2004-01-13 23:22:45.000000000 -0800 +++ 25-akpm/include/asm-ppc64/smp.h 2004-01-13 23:22:45.000000000 -0800 @@ -34,9 +34,28 @@ extern void smp_send_xmon_break(int cpu) struct pt_regs; extern void smp_message_recv(int, struct pt_regs *); -#define cpu_possible(cpu) paca[cpu].active #define smp_processor_id() (get_paca()->xPacaIndex) +#define hard_smp_processor_id() (get_paca()->xHwProcNum) + +/* + * Retrieve the state of a CPU: + * online: CPU is in a normal run state + * possible: CPU is a candidate to be made online + * available: CPU is candidate for the 'possible' pool + * Used to get SMT threads started at boot time. + * present_at_boot: CPU was available at boot time. Used in DLPAR + * code to handle special cases for processor start up. + */ +extern cpumask_t cpu_present_at_boot; +extern cpumask_t cpu_online_map; +extern cpumask_t cpu_possible_map; +extern cpumask_t cpu_available_map; + +#define cpu_present_at_boot(cpu) cpu_isset(cpu, cpu_present_at_boot) +#define cpu_online(cpu) cpu_isset(cpu, cpu_online_map) +#define cpu_possible(cpu) cpu_isset(cpu, cpu_possible_map) +#define cpu_available(cpu) cpu_isset(cpu, cpu_available_map) /* Since OpenPIC has only 4 IPIs, we use slightly different message numbers. * @@ -52,5 +71,7 @@ void smp_init_pSeries(void); #endif /* __ASSEMBLY__ */ #endif /* !(CONFIG_SMP) */ +#define get_hard_smp_processor_id(CPU) (paca[(CPU)].xHwProcNum) +#define set_hard_smp_processor_id(CPU, VAL) do { (paca[(CPU)].xHwProcNum = VAL); } while (0) #endif /* !(_PPC64_SMP_H) */ #endif /* __KERNEL__ */ diff -puN include/asm-ppc64/processor.h~ppc64-logical_cpu include/asm-ppc64/processor.h --- 25/include/asm-ppc64/processor.h~ppc64-logical_cpu 2004-01-13 23:22:45.000000000 -0800 +++ 25-akpm/include/asm-ppc64/processor.h 2004-01-13 23:22:45.000000000 -0800 @@ -371,6 +371,7 @@ #define PV_ICESTAR 0x0036 #define PV_SSTAR 0x0037 #define PV_POWER4p 0x0038 +#define PV_POWER5 0x003A #define PV_630 0x0040 #define PV_630p 0x0041 diff -puN arch/ppc64/kernel/xics.c~ppc64-logical_cpu arch/ppc64/kernel/xics.c --- 25/arch/ppc64/kernel/xics.c~ppc64-logical_cpu 2004-01-13 23:22:45.000000000 -0800 +++ 25-akpm/arch/ppc64/kernel/xics.c 2004-01-13 23:22:45.000000000 -0800 @@ -202,7 +202,7 @@ static void pSeriesLP_qirr_info(int n_cp { unsigned long lpar_rc; - lpar_rc = plpar_ipi(n_cpu, value); + lpar_rc = plpar_ipi(get_hard_smp_processor_id(n_cpu), value); if (lpar_rc != H_Success) panic("bad return code qirr - rc = %lx\n", lpar_rc); } @@ -441,7 +441,7 @@ nextnode: np; np = of_find_node_by_type(np, "cpu")) { ireg = (uint *)get_property(np, "reg", &ilen); - if (ireg && ireg[0] == smp_processor_id()) { + if (ireg && ireg[0] == hard_smp_processor_id()) { ireg = (uint *)get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen); i = ilen / sizeof(int); if (ireg && i > 0) { @@ -478,8 +478,8 @@ nextnode: for (i = 0; i < NR_CPUS; ++i) { if (!cpu_possible(i)) continue; - xics_per_cpu[i] = __ioremap((ulong)inodes[i].addr, - (ulong)inodes[i].size, + xics_per_cpu[i] = __ioremap((ulong)inodes[get_hard_smp_processor_id(i)].addr, + (ulong)inodes[get_hard_smp_processor_id(i)].size, _PAGE_NO_CACHE); } #else @@ -570,7 +570,7 @@ void xics_set_affinity(unsigned int virq cpus_and(tmp, cpu_online_map, cpumask); if (cpus_empty(tmp)) goto out; - newmask = first_cpu(cpumask); + newmask = get_hard_smp_processor_id(first_cpu(cpumask)); } status = rtas_call(ibm_set_xive, 3, 1, NULL, _