aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/s390/include/asm/uaccess.h2
-rw-r--r--arch/s390/kernel/ipl.c15
-rw-r--r--arch/s390/kernel/os_info.c2
-rw-r--r--arch/s390/kernel/setup.c12
-rw-r--r--arch/s390/mm/maccess.c38
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
379extern int memcpy_real(void *, void *, size_t); 379extern int memcpy_real(void *, void *, size_t);
380extern void copy_to_absolute_zero(void *dest, void *src, size_t count); 380extern void memcpy_absolute(void *, void *, size_t);
381extern int copy_to_user_real(void __user *dest, void *src, size_t count); 381extern int copy_to_user_real(void __user *dest, void *src, size_t count);
382extern int copy_from_user_real(void *dest, void __user *src, size_t count); 382extern 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
1529static void dump_reipl_run(struct shutdown_trigger *trigger) 1529static 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 */
106void copy_to_absolute_zero(void *dest, void *src, size_t count) 106void 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 */
193static 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();