// SPDX-License-Identifier: GPL-2.0 /* * Copyright IBM Corp. 2004, 2010 * Interface implementation for communication with the z/VM control program * * Author(s): Christian Borntraeger <borntraeger@de.ibm.com> * * z/VMs CP offers the possibility to issue commands via the diagnose code 8 * this driver implements a character device that issues these commands and * returns the answer of CP. * * The idea of this driver is based on cpint from Neale Ferguson and #CP in CMS
*/
if (count > 240) return -EINVAL;
cmd = memdup_user_nul(buff, count); if (IS_ERR(cmd)) return PTR_ERR(cmd);
session = file->private_data; if (mutex_lock_interruptible(&session->mutex)) {
kfree(cmd); return -ERESTARTSYS;
} if (!session->response)
vmcp_response_alloc(session); if (!session->response) {
mutex_unlock(&session->mutex);
kfree(cmd); return -ENOMEM;
}
debug_text_event(vmcp_debug, 1, cmd);
session->resp_size = cpcmd(cmd, session->response, session->bufsize,
&session->resp_code);
mutex_unlock(&session->mutex);
kfree(cmd);
*ppos = 0; /* reset the file pointer after a command */ return count;
}
/* * These ioctls are available, as the semantics of the diagnose 8 call * does not fit very well into a Linux call. Diagnose X'08' is described in * CP Programming Services SC24-6084-00 * * VMCP_GETCODE: gives the CP return code back to user space * VMCP_SETBUF: sets the response buffer for the next write call. diagnose 8 * expects adjacent pages in real storage and to make matters worse, we * dont know the size of the response. Therefore we default to PAGESIZE and * let userspace to change the response size, if userspace expects a bigger * response
*/ staticlong vmcp_ioctl(struct file *file, unsignedint cmd, unsignedlong arg)
{ struct vmcp_session *session; int ret = -ENOTTY; int __user *argp;
session = file->private_data; if (is_compat_task())
argp = compat_ptr(arg); else
argp = (int __user *)arg; if (mutex_lock_interruptible(&session->mutex)) return -ERESTARTSYS; switch (cmd) { case VMCP_GETCODE:
ret = put_user(session->resp_code, argp); break; case VMCP_SETBUF:
vmcp_response_free(session);
ret = get_user(session->bufsize, argp); if (ret)
session->bufsize = PAGE_SIZE; if (!session->bufsize || get_order(session->bufsize) > 8) {
session->bufsize = PAGE_SIZE;
ret = -EINVAL;
} break; case VMCP_GETSIZE:
ret = put_user(session->resp_size, argp); break; default: break;
}
mutex_unlock(&session->mutex); return ret;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.