diff options
-rw-r--r-- | arch/s390/include/asm/uaccess.h | 2 | ||||
-rw-r--r-- | arch/s390/kernel/ipl.c | 15 | ||||
-rw-r--r-- | arch/s390/kernel/os_info.c | 2 | ||||
-rw-r--r-- | arch/s390/kernel/setup.c | 12 | ||||
-rw-r--r-- | arch/s390/mm/maccess.c | 38 |
5 files changed, 34 insertions, 35 deletions
diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h index 8f2cada4f7c9..8e83da66df0d 100644 --- a/arch/s390/include/asm/uaccess.h +++ b/arch/s390/include/asm/uaccess.h | |||
@@ -377,7 +377,7 @@ clear_user(void __user *to, unsigned long n) | |||
377 | } | 377 | } |
378 | 378 | ||
379 | extern int memcpy_real(void *, void *, size_t); | 379 | extern int memcpy_real(void *, void *, size_t); |
380 | extern void copy_to_absolute_zero(void *dest, void *src, size_t count); | 380 | extern void memcpy_absolute(void *, void *, size_t); |
381 | extern int copy_to_user_real(void __user *dest, void *src, size_t count); | 381 | extern int copy_to_user_real(void __user *dest, void *src, size_t count); |
382 | extern int copy_from_user_real(void *dest, void __user *src, size_t count); | 382 | extern int copy_from_user_real(void *dest, void __user *src, size_t count); |
383 | 383 | ||
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index dcfdcb3ea163..2f6cfd460cb6 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c | |||
@@ -1528,12 +1528,15 @@ static struct shutdown_action __refdata dump_action = { | |||
1528 | 1528 | ||
1529 | static void dump_reipl_run(struct shutdown_trigger *trigger) | 1529 | static void dump_reipl_run(struct shutdown_trigger *trigger) |
1530 | { | 1530 | { |
1531 | u32 csum; | 1531 | struct { |
1532 | 1532 | void *addr; | |
1533 | csum = csum_partial(reipl_block_actual, reipl_block_actual->hdr.len, 0); | 1533 | __u32 csum; |
1534 | copy_to_absolute_zero(&S390_lowcore.ipib_checksum, &csum, sizeof(csum)); | 1534 | } __packed ipib; |
1535 | copy_to_absolute_zero(&S390_lowcore.ipib, &reipl_block_actual, | 1535 | |
1536 | sizeof(reipl_block_actual)); | 1536 | ipib.csum = csum_partial(reipl_block_actual, |
1537 | reipl_block_actual->hdr.len, 0); | ||
1538 | ipib.addr = reipl_block_actual; | ||
1539 | memcpy_absolute(&S390_lowcore.ipib, &ipib, sizeof(ipib)); | ||
1537 | dump_run(trigger); | 1540 | dump_run(trigger); |
1538 | } | 1541 | } |
1539 | 1542 | ||
diff --git a/arch/s390/kernel/os_info.c b/arch/s390/kernel/os_info.c index f2fe18f3f01f..95fa5ac6c4ce 100644 --- a/arch/s390/kernel/os_info.c +++ b/arch/s390/kernel/os_info.c | |||
@@ -60,7 +60,7 @@ void __init os_info_init(void) | |||
60 | os_info.version_minor = OS_INFO_VERSION_MINOR; | 60 | os_info.version_minor = OS_INFO_VERSION_MINOR; |
61 | os_info.magic = OS_INFO_MAGIC; | 61 | os_info.magic = OS_INFO_MAGIC; |
62 | os_info.csum = os_info_csum(&os_info); | 62 | os_info.csum = os_info_csum(&os_info); |
63 | copy_to_absolute_zero(&S390_lowcore.os_info, &ptr, sizeof(ptr)); | 63 | memcpy_absolute(&S390_lowcore.os_info, &ptr, sizeof(ptr)); |
64 | } | 64 | } |
65 | 65 | ||
66 | #ifdef CONFIG_CRASH_DUMP | 66 | #ifdef CONFIG_CRASH_DUMP |
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 06264ae8ccd9..489d1d8d96b0 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -428,10 +428,12 @@ static void __init setup_lowcore(void) | |||
428 | lc->restart_fn = (unsigned long) do_restart; | 428 | lc->restart_fn = (unsigned long) do_restart; |
429 | lc->restart_data = 0; | 429 | lc->restart_data = 0; |
430 | lc->restart_source = -1UL; | 430 | lc->restart_source = -1UL; |
431 | memcpy(&S390_lowcore.restart_stack, &lc->restart_stack, | 431 | |
432 | 4*sizeof(unsigned long)); | 432 | /* Setup absolute zero lowcore */ |
433 | copy_to_absolute_zero(&S390_lowcore.restart_psw, | 433 | memcpy_absolute(&S390_lowcore.restart_stack, &lc->restart_stack, |
434 | &lc->restart_psw, sizeof(psw_t)); | 434 | 4 * sizeof(unsigned long)); |
435 | memcpy_absolute(&S390_lowcore.restart_psw, &lc->restart_psw, | ||
436 | sizeof(lc->restart_psw)); | ||
435 | 437 | ||
436 | set_prefix((u32)(unsigned long) lc); | 438 | set_prefix((u32)(unsigned long) lc); |
437 | lowcore_ptr[0] = lc; | 439 | lowcore_ptr[0] = lc; |
@@ -598,7 +600,7 @@ static void __init setup_vmcoreinfo(void) | |||
598 | #ifdef CONFIG_KEXEC | 600 | #ifdef CONFIG_KEXEC |
599 | unsigned long ptr = paddr_vmcoreinfo_note(); | 601 | unsigned long ptr = paddr_vmcoreinfo_note(); |
600 | 602 | ||
601 | copy_to_absolute_zero(&S390_lowcore.vmcore_info, &ptr, sizeof(ptr)); | 603 | memcpy_absolute(&S390_lowcore.vmcore_info, &ptr, sizeof(ptr)); |
602 | #endif | 604 | #endif |
603 | } | 605 | } |
604 | 606 | ||
diff --git a/arch/s390/mm/maccess.c b/arch/s390/mm/maccess.c index 795a0a9bb2eb..921fa541dc04 100644 --- a/arch/s390/mm/maccess.c +++ b/arch/s390/mm/maccess.c | |||
@@ -101,19 +101,27 @@ int memcpy_real(void *dest, void *src, size_t count) | |||
101 | } | 101 | } |
102 | 102 | ||
103 | /* | 103 | /* |
104 | * Copy memory to absolute zero | 104 | * Copy memory in absolute mode (kernel to kernel) |
105 | */ | 105 | */ |
106 | void copy_to_absolute_zero(void *dest, void *src, size_t count) | 106 | void memcpy_absolute(void *dest, void *src, size_t count) |
107 | { | 107 | { |
108 | unsigned long cr0; | 108 | unsigned long cr0, flags, prefix; |
109 | 109 | ||
110 | BUG_ON((unsigned long) dest + count >= sizeof(struct _lowcore)); | 110 | flags = arch_local_irq_save(); |
111 | preempt_disable(); | ||
112 | __ctl_store(cr0, 0, 0); | 111 | __ctl_store(cr0, 0, 0); |
113 | __ctl_clear_bit(0, 28); /* disable lowcore protection */ | 112 | __ctl_clear_bit(0, 28); /* disable lowcore protection */ |
114 | memcpy_real(dest + store_prefix(), src, count); | 113 | prefix = store_prefix(); |
114 | if (prefix) { | ||
115 | local_mcck_disable(); | ||
116 | set_prefix(0); | ||
117 | memcpy(dest, src, count); | ||
118 | set_prefix(prefix); | ||
119 | local_mcck_enable(); | ||
120 | } else { | ||
121 | memcpy(dest, src, count); | ||
122 | } | ||
115 | __ctl_load(cr0, 0, 0); | 123 | __ctl_load(cr0, 0, 0); |
116 | preempt_enable(); | 124 | arch_local_irq_restore(flags); |
117 | } | 125 | } |
118 | 126 | ||
119 | /* | 127 | /* |
@@ -188,20 +196,6 @@ static int is_swapped(unsigned long addr) | |||
188 | } | 196 | } |
189 | 197 | ||
190 | /* | 198 | /* |
191 | * Return swapped prefix or zero page address | ||
192 | */ | ||
193 | static unsigned long get_swapped(unsigned long addr) | ||
194 | { | ||
195 | unsigned long prefix = store_prefix(); | ||
196 | |||
197 | if (addr < sizeof(struct _lowcore)) | ||
198 | return addr + prefix; | ||
199 | if (addr >= prefix && addr < prefix + sizeof(struct _lowcore)) | ||
200 | return addr - prefix; | ||
201 | return addr; | ||
202 | } | ||
203 | |||
204 | /* | ||
205 | * Convert a physical pointer for /dev/mem access | 199 | * Convert a physical pointer for /dev/mem access |
206 | * | 200 | * |
207 | * For swapped prefix pages a new buffer is returned that contains a copy of | 201 | * For swapped prefix pages a new buffer is returned that contains a copy of |
@@ -218,7 +212,7 @@ void *xlate_dev_mem_ptr(unsigned long addr) | |||
218 | size = PAGE_SIZE - (addr & ~PAGE_MASK); | 212 | size = PAGE_SIZE - (addr & ~PAGE_MASK); |
219 | bounce = (void *) __get_free_page(GFP_ATOMIC); | 213 | bounce = (void *) __get_free_page(GFP_ATOMIC); |
220 | if (bounce) | 214 | if (bounce) |
221 | memcpy_real(bounce, (void *) get_swapped(addr), size); | 215 | memcpy_absolute(bounce, (void *) addr, size); |
222 | } | 216 | } |
223 | preempt_enable(); | 217 | preempt_enable(); |
224 | put_online_cpus(); | 218 | put_online_cpus(); |