diff options
Diffstat (limited to 'arch/s390/kernel/smp.c')
-rw-r--r-- | arch/s390/kernel/smp.c | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index cc8c484984e..fd8e3111a4e 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -1,7 +1,7 @@ /* * arch/s390/kernel/smp.c * - * Copyright IBM Corp. 1999,2007 + * Copyright IBM Corp. 1999, 2009 * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), * Martin Schwidefsky (schwidefsky@de.ibm.com) * Heiko Carstens (heiko.carstens@de.ibm.com) @@ -1031,6 +1031,42 @@ out: static SYSDEV_CLASS_ATTR(dispatching, 0644, dispatching_show, dispatching_store); +/* + * If the resume kernel runs on another cpu than the suspended kernel, + * we have to switch the cpu IDs in the logical map. + */ +void smp_switch_boot_cpu_in_resume(u32 resume_phys_cpu_id, + struct _lowcore *suspend_lowcore) +{ + int cpu, suspend_cpu_id, resume_cpu_id; + u32 suspend_phys_cpu_id; + + suspend_phys_cpu_id = __cpu_logical_map[suspend_lowcore->cpu_nr]; + suspend_cpu_id = suspend_lowcore->cpu_nr; + + for_each_present_cpu(cpu) { + if (__cpu_logical_map[cpu] == resume_phys_cpu_id) { + resume_cpu_id = cpu; + goto found; + } + } + panic("Could not find resume cpu in logical map.\n"); + +found: + printk("Resume cpu ID: %i/%i\n", resume_phys_cpu_id, resume_cpu_id); + printk("Suspend cpu ID: %i/%i\n", suspend_phys_cpu_id, suspend_cpu_id); + + __cpu_logical_map[resume_cpu_id] = suspend_phys_cpu_id; + __cpu_logical_map[suspend_cpu_id] = resume_phys_cpu_id; + + lowcore_ptr[suspend_cpu_id]->cpu_addr = resume_phys_cpu_id; +} + +u32 smp_get_phys_cpu_id(void) +{ + return __cpu_logical_map[smp_processor_id()]; +} + static int __init topology_init(void) { int cpu; |