aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/mm/maccess.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/mm/maccess.c')
-rw-r--r--arch/s390/mm/maccess.c38
1 files changed, 16 insertions, 22 deletions
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();