aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Holzheu <holzheu@linux.vnet.ibm.com>2011-05-10 11:13:41 -0400
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2011-05-10 11:13:43 -0400
commit83ace2701b81be549cca7af33c5b0499cb2602d6 (patch)
tree17c74e48a1d67b7691fbdd4955835f16db76ae88
parent91d378088b104f8e31baba8c518f32a7a219d58c (diff)
[S390] replace diag10() with diag10_range() function
Currently the diag10() function can only release one page. For exploiters that have to call diag10 on a contiguous memory region this is suboptimal. This patch replaces the diag10() function with diag10_range() that is able to release multiple pages. In addition to that the new function now allows to release memory with addresses higher than 2047 MiB. This was due to a restriction of the diagnose implementation under z/VM prior to release 5.2. Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--arch/s390/include/asm/diag.h17
-rw-r--r--arch/s390/kernel/diag.c21
-rw-r--r--arch/s390/mm/cmm.c2
3 files changed, 16 insertions, 24 deletions
diff --git a/arch/s390/include/asm/diag.h b/arch/s390/include/asm/diag.h
index 72b2e2f2d32d..7e91c58072e2 100644
--- a/arch/s390/include/asm/diag.h
+++ b/arch/s390/include/asm/diag.h
@@ -9,9 +9,22 @@
9#define _ASM_S390_DIAG_H 9#define _ASM_S390_DIAG_H
10 10
11/* 11/*
12 * Diagnose 10: Release pages 12 * Diagnose 10: Release page range
13 */ 13 */
14extern void diag10(unsigned long addr); 14static inline void diag10_range(unsigned long start_pfn, unsigned long num_pfn)
15{
16 unsigned long start_addr, end_addr;
17
18 start_addr = start_pfn << PAGE_SHIFT;
19 end_addr = (start_pfn + num_pfn - 1) << PAGE_SHIFT;
20
21 asm volatile(
22 "0: diag %0,%1,0x10\n"
23 "1:\n"
24 EX_TABLE(0b, 1b)
25 EX_TABLE(1b, 1b)
26 : : "a" (start_addr), "a" (end_addr));
27}
15 28
16/* 29/*
17 * Diagnose 14: Input spool file manipulation 30 * Diagnose 14: Input spool file manipulation
diff --git a/arch/s390/kernel/diag.c b/arch/s390/kernel/diag.c
index c032d11da8a1..8237fc07ac79 100644
--- a/arch/s390/kernel/diag.c
+++ b/arch/s390/kernel/diag.c
@@ -9,27 +9,6 @@
9#include <asm/diag.h> 9#include <asm/diag.h>
10 10
11/* 11/*
12 * Diagnose 10: Release pages
13 */
14void diag10(unsigned long addr)
15{
16 if (addr >= 0x7ff00000)
17 return;
18 asm volatile(
19#ifdef CONFIG_64BIT
20 " sam31\n"
21 " diag %0,%0,0x10\n"
22 "0: sam64\n"
23#else
24 " diag %0,%0,0x10\n"
25 "0:\n"
26#endif
27 EX_TABLE(0b, 0b)
28 : : "a" (addr));
29}
30EXPORT_SYMBOL(diag10);
31
32/*
33 * Diagnose 14: Input spool file manipulation 12 * Diagnose 14: Input spool file manipulation
34 */ 13 */
35int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode) 14int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode)
diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c
index c66ffd8dbbb7..1f1dba9dcf58 100644
--- a/arch/s390/mm/cmm.c
+++ b/arch/s390/mm/cmm.c
@@ -91,7 +91,7 @@ static long cmm_alloc_pages(long nr, long *counter,
91 } else 91 } else
92 free_page((unsigned long) npa); 92 free_page((unsigned long) npa);
93 } 93 }
94 diag10(addr); 94 diag10_range(addr >> PAGE_SHIFT, 1);
95 pa->pages[pa->index++] = addr; 95 pa->pages[pa->index++] = addr;
96 (*counter)++; 96 (*counter)++;
97 spin_unlock(&cmm_lock); 97 spin_unlock(&cmm_lock);