summaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/cpcmd.c
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2017-08-07 15:16:15 +0200
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2017-08-09 15:09:35 +0200
commitcd4386a931b6310b05559d2e28efda04d30ab593 (patch)
treed1fbc2a6a8e86af9308ce8713e842e6717471c8e /arch/s390/kernel/cpcmd.c
parents390/vmcp: fix uaccess check and avoid undefined behavior (diff)
downloadlinux-cd4386a931b6310b05559d2e28efda04d30ab593.tar.xz
linux-cd4386a931b6310b05559d2e28efda04d30ab593.zip
s390/cpcmd,vmcp: avoid GFP_DMA allocations
According to the CP Programming Services manual Diagnose Code 8 "Virtual Console Function" can be used in all addressing modes. Also the input and output buffers do not have a limitation which specifies they need to be below the 2GB line. This is true at least since z/VM 5.4. Therefore remove the sam31/64 instructions and allow for simple GFP_KERNEL allocations. This makes it easier to allocate a 1MB page if the user requested such a large return buffer. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/cpcmd.c')
-rw-r--r--arch/s390/kernel/cpcmd.c13
1 files changed, 4 insertions, 9 deletions
diff --git a/arch/s390/kernel/cpcmd.c b/arch/s390/kernel/cpcmd.c
index 9f0e4a2785f7..63bc6603e0ed 100644
--- a/arch/s390/kernel/cpcmd.c
+++ b/arch/s390/kernel/cpcmd.c
@@ -14,6 +14,7 @@
#include <linux/spinlock.h>
#include <linux/stddef.h>
#include <linux/string.h>
+#include <linux/mm.h>
#include <asm/diag.h>
#include <asm/ebcdic.h>
#include <asm/cpcmd.h>
@@ -28,9 +29,7 @@ static int diag8_noresponse(int cmdlen)
register unsigned long reg3 asm ("3") = cmdlen;
asm volatile(
- " sam31\n"
" diag %1,%0,0x8\n"
- " sam64\n"
: "+d" (reg3) : "d" (reg2) : "cc");
return reg3;
}
@@ -43,9 +42,7 @@ static int diag8_response(int cmdlen, char *response, int *rlen)
register unsigned long reg5 asm ("5") = *rlen;
asm volatile(
- " sam31\n"
" diag %2,%0,0x8\n"
- " sam64\n"
" brc 8,1f\n"
" agr %1,%4\n"
"1:\n"
@@ -57,7 +54,6 @@ static int diag8_response(int cmdlen, char *response, int *rlen)
/*
* __cpcmd has some restrictions over cpcmd
- * - the response buffer must reside below 2GB (if any)
* - __cpcmd is unlocked and therefore not SMP-safe
*/
int __cpcmd(const char *cmd, char *response, int rlen, int *response_code)
@@ -88,13 +84,12 @@ EXPORT_SYMBOL(__cpcmd);
int cpcmd(const char *cmd, char *response, int rlen, int *response_code)
{
+ unsigned long flags;
char *lowbuf;
int len;
- unsigned long flags;
- if ((virt_to_phys(response) != (unsigned long) response) ||
- (((unsigned long)response + rlen) >> 31)) {
- lowbuf = kmalloc(rlen, GFP_KERNEL | GFP_DMA);
+ if (is_vmalloc_or_module_addr(response)) {
+ lowbuf = kmalloc(rlen, GFP_KERNEL);
if (!lowbuf) {
pr_warn("The cpcmd kernel function failed to allocate a response buffer\n");
return -ENOMEM;