summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/disp/priocntl.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/disp/priocntl.c')
-rw-r--r--usr/src/uts/common/disp/priocntl.c87
1 files changed, 54 insertions, 33 deletions
diff --git a/usr/src/uts/common/disp/priocntl.c b/usr/src/uts/common/disp/priocntl.c
index 3c1a271155..3bb90cf1fa 100644
--- a/usr/src/uts/common/disp/priocntl.c
+++ b/usr/src/uts/common/disp/priocntl.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -81,7 +80,7 @@ struct stprmargs {
* between the 64-bit kernel ABI and the 32-bit user ABI.
*/
static int
-copyin_vaparms32(caddr_t arg, pc_vaparms_t *vap)
+copyin_vaparms32(caddr_t arg, pc_vaparms_t *vap, uio_seg_t seg)
{
pc_vaparms32_t vaparms32;
pc_vaparm32_t *src;
@@ -90,7 +89,8 @@ copyin_vaparms32(caddr_t arg, pc_vaparms_t *vap)
ASSERT(get_udatamodel() == DATAMODEL_ILP32);
- if (copyin(arg, &vaparms32, sizeof (vaparms32)))
+ if ((seg == UIO_USERSPACE ? copyin : kcopy)(arg, &vaparms32,
+ sizeof (vaparms32)))
return (EFAULT);
vap->pc_vaparmscnt = vaparms32.pc_vaparmscnt;
@@ -104,13 +104,13 @@ copyin_vaparms32(caddr_t arg, pc_vaparms_t *vap)
return (0);
}
-#define COPYIN_VAPARMS(arg, vap, size) \
+#define COPYIN_VAPARMS(arg, vap, size, seg) \
(get_udatamodel() == DATAMODEL_NATIVE ? \
- copyin(arg, vap, size) : copyin_vaparms32(arg, vap))
+ (*copyinfn)(arg, vap, size) : copyin_vaparms32(arg, vap, seg))
#else
-#define COPYIN_VAPARMS(arg, vap, size) copyin(arg, vap, size)
+#define COPYIN_VAPARMS(arg, vap, size, seg) (*copyinfn)(arg, vap, size)
#endif
@@ -123,7 +123,8 @@ extern int threadcmp(struct pcmpargs *, kthread_id_t);
* The priocntl system call.
*/
long
-priocntlsys(int pc_version, procset_t *psp, int cmd, caddr_t arg, caddr_t arg2)
+priocntl_common(int pc_version, procset_t *psp, int cmd, caddr_t arg,
+ caddr_t arg2, uio_seg_t seg)
{
pcinfo_t pcinfo;
pcparms_t pcparms;
@@ -144,6 +145,8 @@ priocntlsys(int pc_version, procset_t *psp, int cmd, caddr_t arg, caddr_t arg2)
int rv = 0;
pid_t saved_pid;
id_t classid;
+ int (*copyinfn)(const void *, void *, size_t);
+ int (*copyoutfn)(const void *, void *, size_t);
/*
* First just check the version number. Right now there is only
@@ -157,6 +160,14 @@ priocntlsys(int pc_version, procset_t *psp, int cmd, caddr_t arg, caddr_t arg2)
if (pc_version != PC_VERSION)
return (set_errno(EINVAL));
+ if (seg == UIO_USERSPACE) {
+ copyinfn = copyin;
+ copyoutfn = copyout;
+ } else {
+ copyinfn = kcopy;
+ copyoutfn = kcopy;
+ }
+
switch (cmd) {
case PC_GETCID:
/*
@@ -171,7 +182,7 @@ priocntlsys(int pc_version, procset_t *psp, int cmd, caddr_t arg, caddr_t arg2)
rv = loaded_classes;
break;
} else {
- if (copyin(arg, &pcinfo, sizeof (pcinfo)))
+ if ((*copyinfn)(arg, &pcinfo, sizeof (pcinfo)))
return (set_errno(EFAULT));
}
@@ -204,7 +215,7 @@ priocntlsys(int pc_version, procset_t *psp, int cmd, caddr_t arg, caddr_t arg2)
if (error)
return (set_errno(error));
- if (copyout(&pcinfo, arg, sizeof (pcinfo)))
+ if ((*copyoutfn)(&pcinfo, arg, sizeof (pcinfo)))
return (set_errno(EFAULT));
rv = loaded_classes;
@@ -221,7 +232,7 @@ priocntlsys(int pc_version, procset_t *psp, int cmd, caddr_t arg, caddr_t arg2)
rv = loaded_classes;
break;
} else {
- if (copyin(arg, &pcinfo, sizeof (pcinfo)))
+ if ((*copyinfn)(arg, &pcinfo, sizeof (pcinfo)))
return (set_errno(EFAULT));
}
@@ -245,7 +256,7 @@ priocntlsys(int pc_version, procset_t *psp, int cmd, caddr_t arg, caddr_t arg2)
if (error)
return (set_errno(error));
- if (copyout(&pcinfo, arg, sizeof (pcinfo)))
+ if ((*copyoutfn)(&pcinfo, arg, sizeof (pcinfo)))
return (set_errno(EFAULT));
rv = loaded_classes;
@@ -259,13 +270,14 @@ priocntlsys(int pc_version, procset_t *psp, int cmd, caddr_t arg, caddr_t arg2)
* because it's done on a per thread basis by parmsset().
*/
if (cmd == PC_SETPARMS) {
- if (copyin(arg, &pcparms, sizeof (pcparms)))
+ if ((*copyinfn)(arg, &pcparms, sizeof (pcparms)))
return (set_errno(EFAULT));
error = parmsin(&pcparms, NULL);
} else {
- if (copyin(arg, clname, PC_CLNMSZ) ||
- COPYIN_VAPARMS(arg2, &vaparms, sizeof (vaparms)))
+ if ((*copyinfn)(arg, clname, PC_CLNMSZ) ||
+ COPYIN_VAPARMS(arg2, &vaparms, sizeof (vaparms),
+ seg))
return (set_errno(EFAULT));
clname[PC_CLNMSZ-1] = '\0';
@@ -281,7 +293,7 @@ priocntlsys(int pc_version, procset_t *psp, int cmd, caddr_t arg, caddr_t arg2)
/*
* Get the procset from the user.
*/
- if (copyin(psp, &procset, sizeof (procset)))
+ if ((*copyinfn)(psp, &procset, sizeof (procset)))
return (set_errno(EFAULT));
/*
@@ -372,11 +384,11 @@ priocntlsys(int pc_version, procset_t *psp, int cmd, caddr_t arg, caddr_t arg2)
case PC_GETPARMS:
case PC_GETXPARMS:
if (cmd == PC_GETPARMS) {
- if (copyin(arg, &pcparms, sizeof (pcparms)))
+ if ((*copyinfn)(arg, &pcparms, sizeof (pcparms)))
return (set_errno(EFAULT));
} else {
if (arg != NULL) {
- if (copyin(arg, clname, PC_CLNMSZ))
+ if ((*copyinfn)(arg, clname, PC_CLNMSZ))
return (set_errno(EFAULT));
clname[PC_CLNMSZ-1] = '\0';
@@ -385,7 +397,9 @@ priocntlsys(int pc_version, procset_t *psp, int cmd, caddr_t arg, caddr_t arg2)
return (set_errno(EINVAL));
} else
pcparms.pc_cid = PC_CLNULL;
- if (COPYIN_VAPARMS(arg2, &vaparms, sizeof (vaparms)))
+
+ if (COPYIN_VAPARMS(arg2, &vaparms, sizeof (vaparms),
+ seg))
return (set_errno(EFAULT));
}
@@ -393,7 +407,7 @@ priocntlsys(int pc_version, procset_t *psp, int cmd, caddr_t arg, caddr_t arg2)
(pcparms.pc_cid < 1 && pcparms.pc_cid != PC_CLNULL))
return (set_errno(EINVAL));
- if (copyin(psp, &procset, sizeof (procset)))
+ if ((*copyinfn)(psp, &procset, sizeof (procset)))
return (set_errno(EFAULT));
/*
@@ -590,9 +604,10 @@ priocntlsys(int pc_version, procset_t *psp, int cmd, caddr_t arg, caddr_t arg2)
return (set_errno(error));
if (cmd == PC_GETPARMS) {
- if (copyout(&pcparms, arg, sizeof (pcparms)))
+ if ((*copyoutfn)(&pcparms, arg, sizeof (pcparms)))
return (set_errno(EFAULT));
- } else if ((error = vaparmsout(arg, &pcparms, &vaparms)) != 0)
+ } else if ((error = vaparmsout(arg, &pcparms, &vaparms,
+ seg)) != 0)
return (set_errno(error));
/*
@@ -603,14 +618,14 @@ priocntlsys(int pc_version, procset_t *psp, int cmd, caddr_t arg, caddr_t arg2)
case PC_ADMIN:
if (get_udatamodel() == DATAMODEL_NATIVE) {
- if (copyin(arg, &pcadmin, sizeof (pcadmin_t)))
+ if ((*copyinfn)(arg, &pcadmin, sizeof (pcadmin_t)))
return (set_errno(EFAULT));
#ifdef _SYSCALL32_IMPL
} else {
/* pcadmin struct from ILP32 callers */
pcadmin32_t pcadmin32;
- if (copyin(arg, &pcadmin32, sizeof (pcadmin32_t)))
+ if ((*copyinfn)(arg, &pcadmin32, sizeof (pcadmin32_t)))
return (set_errno(EFAULT));
pcadmin.pc_cid = pcadmin32.pc_cid;
pcadmin.pc_cladmin = (caddr_t)(uintptr_t)
@@ -632,7 +647,7 @@ priocntlsys(int pc_version, procset_t *psp, int cmd, caddr_t arg, caddr_t arg2)
break;
case PC_GETPRIRANGE:
- if (copyin(arg, &pcpri, sizeof (pcpri_t)))
+ if ((*copyinfn)(arg, &pcpri, sizeof (pcpri_t)))
return (set_errno(EFAULT));
if (pcpri.pc_cid >= loaded_classes || pcpri.pc_cid < 0)
@@ -640,7 +655,7 @@ priocntlsys(int pc_version, procset_t *psp, int cmd, caddr_t arg, caddr_t arg2)
error = CL_GETCLPRI(&sclass[pcpri.pc_cid], &pcpri);
if (!error) {
- if (copyout(&pcpri, arg, sizeof (pcpri)))
+ if ((*copyoutfn)(&pcpri, arg, sizeof (pcpri)))
return (set_errno(EFAULT));
}
break;
@@ -649,14 +664,14 @@ priocntlsys(int pc_version, procset_t *psp, int cmd, caddr_t arg, caddr_t arg2)
/*
* Get pcnice and procset structures from the user.
*/
- if (copyin(arg, &pcnice, sizeof (pcnice)) ||
- copyin(psp, &procset, sizeof (procset)))
+ if ((*copyinfn)(arg, &pcnice, sizeof (pcnice)) ||
+ (*copyinfn)(psp, &procset, sizeof (procset)))
return (set_errno(EFAULT));
error = donice(&procset, &pcnice);
if (!error && (pcnice.pc_op == PC_GETNICE)) {
- if (copyout(&pcnice, arg, sizeof (pcnice)))
+ if ((*copyoutfn)(&pcnice, arg, sizeof (pcnice)))
return (set_errno(EFAULT));
}
break;
@@ -684,6 +699,12 @@ priocntlsys(int pc_version, procset_t *psp, int cmd, caddr_t arg, caddr_t arg2)
return (error ? (set_errno(error)) : rv);
}
+long
+priocntlsys(int pc_version, procset_t *psp, int cmd, caddr_t arg, caddr_t arg2)
+{
+ return (priocntl_common(pc_version, psp, cmd, arg, arg2,
+ UIO_USERSPACE));
+}
/*
* The proccmp() function is part of the implementation of the
@@ -844,7 +865,7 @@ setparms(proc_t *targpp, struct stprmargs *stprmp)
return (0);
}
-static int
+int
setthreadnice(pcnice_t *pcnice, kthread_t *tp)
{
int error = 0;
@@ -889,7 +910,7 @@ setthreadnice(pcnice_t *pcnice, kthread_t *tp)
return (error);
}
-static int
+int
setprocnice(proc_t *pp, pcnice_t *pcnice)
{
kthread_t *tp;