}
 
 extern int memcpy_real(void *, void *, size_t);
-extern void copy_to_absolute_zero(void *dest, void *src, size_t count);
+extern void memcpy_absolute(void *, void *, size_t);
 extern int copy_to_user_real(void __user *dest, void *src, size_t count);
 extern int copy_from_user_real(void *dest, void __user *src, size_t count);
 
 
 
 static void dump_reipl_run(struct shutdown_trigger *trigger)
 {
-       u32 csum;
-
-       csum = csum_partial(reipl_block_actual, reipl_block_actual->hdr.len, 0);
-       copy_to_absolute_zero(&S390_lowcore.ipib_checksum, &csum, sizeof(csum));
-       copy_to_absolute_zero(&S390_lowcore.ipib, &reipl_block_actual,
-                             sizeof(reipl_block_actual));
+       struct {
+               void    *addr;
+               __u32   csum;
+       } __packed ipib;
+
+       ipib.csum = csum_partial(reipl_block_actual,
+                                reipl_block_actual->hdr.len, 0);
+       ipib.addr = reipl_block_actual;
+       memcpy_absolute(&S390_lowcore.ipib, &ipib, sizeof(ipib));
        dump_run(trigger);
 }
 
 
        os_info.version_minor = OS_INFO_VERSION_MINOR;
        os_info.magic = OS_INFO_MAGIC;
        os_info.csum = os_info_csum(&os_info);
-       copy_to_absolute_zero(&S390_lowcore.os_info, &ptr, sizeof(ptr));
+       memcpy_absolute(&S390_lowcore.os_info, &ptr, sizeof(ptr));
 }
 
 #ifdef CONFIG_CRASH_DUMP
 
        lc->restart_fn = (unsigned long) do_restart;
        lc->restart_data = 0;
        lc->restart_source = -1UL;
-       memcpy(&S390_lowcore.restart_stack, &lc->restart_stack,
-              4*sizeof(unsigned long));
-       copy_to_absolute_zero(&S390_lowcore.restart_psw,
-                             &lc->restart_psw, sizeof(psw_t));
+
+       /* Setup absolute zero lowcore */
+       memcpy_absolute(&S390_lowcore.restart_stack, &lc->restart_stack,
+                       4 * sizeof(unsigned long));
+       memcpy_absolute(&S390_lowcore.restart_psw, &lc->restart_psw,
+                       sizeof(lc->restart_psw));
 
        set_prefix((u32)(unsigned long) lc);
        lowcore_ptr[0] = lc;
 #ifdef CONFIG_KEXEC
        unsigned long ptr = paddr_vmcoreinfo_note();
 
-       copy_to_absolute_zero(&S390_lowcore.vmcore_info, &ptr, sizeof(ptr));
+       memcpy_absolute(&S390_lowcore.vmcore_info, &ptr, sizeof(ptr));
 #endif
 }
 
 
 }
 
 /*
- * Copy memory to absolute zero
+ * Copy memory in absolute mode (kernel to kernel)
  */
-void copy_to_absolute_zero(void *dest, void *src, size_t count)
+void memcpy_absolute(void *dest, void *src, size_t count)
 {
-       unsigned long cr0;
+       unsigned long cr0, flags, prefix;
 
-       BUG_ON((unsigned long) dest + count >= sizeof(struct _lowcore));
-       preempt_disable();
+       flags = arch_local_irq_save();
        __ctl_store(cr0, 0, 0);
        __ctl_clear_bit(0, 28); /* disable lowcore protection */
-       memcpy_real(dest + store_prefix(), src, count);
+       prefix = store_prefix();
+       if (prefix) {
+               local_mcck_disable();
+               set_prefix(0);
+               memcpy(dest, src, count);
+               set_prefix(prefix);
+               local_mcck_enable();
+       } else {
+               memcpy(dest, src, count);
+       }
        __ctl_load(cr0, 0, 0);
-       preempt_enable();
+       arch_local_irq_restore(flags);
 }
 
 /*
        return 0;
 }
 
-/*
- * Return swapped prefix or zero page address
- */
-static unsigned long get_swapped(unsigned long addr)
-{
-       unsigned long prefix = store_prefix();
-
-       if (addr < sizeof(struct _lowcore))
-               return addr + prefix;
-       if (addr >= prefix && addr < prefix + sizeof(struct _lowcore))
-               return addr - prefix;
-       return addr;
-}
-
 /*
  * Convert a physical pointer for /dev/mem access
  *
                size = PAGE_SIZE - (addr & ~PAGE_MASK);
                bounce = (void *) __get_free_page(GFP_ATOMIC);
                if (bounce)
-                       memcpy_real(bounce, (void *) get_swapped(addr), size);
+                       memcpy_absolute(bounce, (void *) addr, size);
        }
        preempt_enable();
        put_online_cpus();