aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/mm/maccess.c
diff options
context:
space:
mode:
authorMichael Holzheu <holzheu@linux.vnet.ibm.com>2012-05-24 08:35:16 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2012-05-30 03:04:49 -0400
commit73bf463efaba6a1efe69349c6d7275d03468adf4 (patch)
tree66a5c2eb6cc72bd8e627ba88931a23e1fdb25248 /arch/s390/mm/maccess.c
parentf4815ac6c935b8e441fe12504d62e0e8ff7f7ce5 (diff)
s390/kernel: Introduce memcpy_absolute() function
This patch introduces the new function memcpy_absolute() that allows to copy memory using absolute addressing. This means that the prefix swap does not apply when this function is used. With this patch also all s390 kernel code that accesses absolute zero now uses the new memcpy_absolute() function. The old and less generic copy_to_absolute_zero() function is removed. Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
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();