Subject: sysarch argument handling
To: None <netbsd-bugs@NetBSD.ORG>
From: None <r_friedl@informatik.uni-kl.de>
List: netbsd-bugs
Date: 11/15/1995 17:15:00
Currently, every sysarch sub-function does a 'copyin' for the
arguments. This could be moved to 'sysarch', similar to 'syscall'.
It is also simpler for the emulation functions, because they don't
have to 'copyout' the the arguments.
--- /mnt/tmp/new/new/new/sys/arch/i386/i386/sys_machdep.c Sun Oct 15 11:35:32 1995
+++ arch/i386/i386/sys_machdep.c Sun Nov 5 22:22:48 1995
@@ -145,26 +145,23 @@
}
int
-i386_get_ldt(p, args, retval)
+i386_get_ldt(p, v, retval)
struct proc *p;
- char *args;
+ void *v;
register_t *retval;
{
int error;
struct pcb *pcb = &p->p_addr->u_pcb;
int nldt, num;
union descriptor *lp;
- struct i386_get_ldt_args ua;
-
- if (error = copyin(args, &ua, sizeof(ua)))
- return (error);
+ struct i386_get_ldt_args *uap = v;
#ifdef DEBUG
- printf("i386_get_ldt: start=%d num=%d descs=%x\n", ua.start,
- ua.num, ua.desc);
+ printf("i386_get_ldt: start=%d num=%d descs=%x\n", uap->start,
+ uap->num, uap->desc);
#endif
- if (ua.start < 0 || ua.num < 0)
+ if (uap->start < 0 || uap->num < 0)
return (EINVAL);
if (pcb->pcb_flags & PCB_USER_LDT) {
@@ -175,13 +172,13 @@
lp = ldt;
}
- if (ua.start > nldt)
+ if (uap->start > nldt)
return (EINVAL);
- lp += ua.start;
- num = min(ua.num, nldt - ua.start);
+ lp += uap->start;
+ num = min(uap->num, nldt - uap->start);
- if (error = copyout(lp, ua.desc, num * sizeof(union descriptor)))
+ if (error = copyout(lp, uap->desc, num * sizeof(union descriptor)))
return (error);
*retval = num;
@@ -189,33 +186,30 @@
}
int
-i386_set_ldt(p, args, retval)
+i386_set_ldt(p, v, retval)
struct proc *p;
- char *args;
+ void *v;
register_t *retval;
{
int error, i, n;
struct pcb *pcb = &p->p_addr->u_pcb;
int fsslot, gsslot;
int s;
- struct i386_set_ldt_args ua;
+ struct i386_set_ldt_args *uap = v;
union descriptor desc;
- if (error = copyin(args, &ua, sizeof(ua)))
- return (error);
-
#ifdef DEBUG
- printf("i386_set_ldt: start=%d num=%d descs=%x\n", ua.start,
- ua.num, ua.desc);
+ printf("i386_set_ldt: start=%d num=%d descs=%x\n", uap->start,
+ uap->num, uap->desc);
#endif
- if (ua.start < 0 || ua.num < 0)
+ if (uap->start < 0 || uap->num < 0)
return (EINVAL);
- if (ua.start > 8192 || (ua.start + ua.num) > 8192)
+ if (uap->start > 8192 || (uap->start + uap->num) > 8192)
return (EINVAL);
/* allocate user ldt */
- if (pcb->pcb_ldt == 0 || (ua.start + ua.num) > pcb->pcb_ldt_len) {
+ if (pcb->pcb_ldt == 0 || (uap->start + uap->num) > pcb->pcb_ldt_len) {
size_t old_len, new_len;
union descriptor *old_ldt, *new_ldt;
@@ -227,7 +221,7 @@
old_ldt = ldt;
pcb->pcb_ldt_len = 512;
}
- while ((ua.start + ua.num) > pcb->pcb_ldt_len)
+ while ((uap->start + uap->num) > pcb->pcb_ldt_len)
pcb->pcb_ldt_len *= 2;
new_len = pcb->pcb_ldt_len * sizeof(union descriptor);
new_ldt = (union descriptor *)kmem_alloc(kernel_map, new_len);
@@ -256,8 +250,8 @@
gsslot = IDXSEL(pcb->pcb_gs);
/* Check descriptors for access violations. */
- for (i = 0, n = ua.start; i < ua.num; i++, n++) {
- if (error = copyin(&ua.desc[i], &desc, sizeof(desc)))
+ for (i = 0, n = uap->start; i < uap->num; i++, n++) {
+ if (error = copyin(&uap->desc[i], &desc, sizeof(desc)))
return (error);
switch (desc.sd.sd_type) {
@@ -302,14 +296,14 @@
s = splhigh();
/* Now actually replace the descriptors. */
- for (i = 0, n = ua.start; i < ua.num; i++, n++) {
- if (error = copyin(&ua.desc[i], &desc, sizeof(desc)))
+ for (i = 0, n = uap->start; i < uap->num; i++, n++) {
+ if (error = copyin(&uap->desc[i], &desc, sizeof(desc)))
goto out;
pcb->pcb_ldt[n] = desc;
}
- *retval = ua.start;
+ *retval = uap->start;
out:
splx(s);
@@ -318,22 +312,19 @@
#endif /* USER_LDT */
int
-i386_iopl(p, args, retval)
+i386_iopl(p, v, retval)
struct proc *p;
- char *args;
+ void *v;
register_t *retval;
{
int error;
struct trapframe *tf = p->p_md.md_regs;
- struct i386_iopl_args ua;
+ struct i386_iopl_args *uap = v;
if (error = suser(p->p_ucred, &p->p_acflag))
return error;
- if (error = copyin(args, &ua, sizeof(ua)))
- return error;
-
- if (ua.iopl)
+ if (uap->iopl)
tf->tf_eflags |= PSL_IOPL;
else
tf->tf_eflags &= ~PSL_IOPL;
@@ -342,40 +333,49 @@
}
int
-i386_get_ioperm(p, args, retval)
+i386_get_ioperm(p, v, retval)
struct proc *p;
- char *args;
+ void *v;
register_t *retval;
{
- int error;
struct pcb *pcb = &p->p_addr->u_pcb;
- struct i386_get_ioperm_args ua;
-
- if (error = copyin(args, &ua, sizeof(ua)))
- return (error);
+ struct i386_get_ioperm_args *uap = v;
- return copyout(pcb->pcb_iomap, ua.iomap, sizeof(pcb->pcb_iomap));
+ return copyout(pcb->pcb_iomap, uap->iomap, sizeof(pcb->pcb_iomap));
}
int
-i386_set_ioperm(p, args, retval)
+i386_set_ioperm(p, v, retval)
struct proc *p;
- char *args;
+ void *v;
register_t *retval;
{
int error;
struct pcb *pcb = &p->p_addr->u_pcb;
- struct i386_set_ioperm_args ua;
+ struct i386_set_ioperm_args *uap = v;
if (error = suser(p->p_ucred, &p->p_acflag))
return error;
- if (error = copyin(args, &ua, sizeof(ua)))
- return (error);
-
- return copyin(ua.iomap, pcb->pcb_iomap, sizeof(pcb->pcb_iomap));
+ return copyin(uap->iomap, pcb->pcb_iomap, sizeof(pcb->pcb_iomap));
}
+#define f(n, name) { n, sizeof(struct __CONCAT(name,_args)), name}
+#define nf() { 0, 0, sys_nosys}
+struct sysent const sysarch_ent[] = {
+#ifdef USER_LDT
+ f(3, i386_get_ldt), /* 0 = i386_get_ldt */
+ f(3, i386_set_ldt), /* 1 = i386_set_ldt */
+#else
+ nf(),
+ nf(),
+#endif
+ f(1, i386_iopl), /* 2 = i386_iopl */
+ f(1, i386_get_ioperm), /* 3 = i386_get_ioperm */
+ f(1, i386_set_ioperm), /* 4 = i386_set_ioperm */
+};
+#undef f
+#undef nf
+#define nsysarch_ent (sizeof (sysarch_ent) / sizeof (*sysarch_ent))
+
int
sys_sysarch(p, v, retval)
struct proc *p;
@@ -386,34 +386,21 @@
syscallarg(int) op;
syscallarg(char *) parms;
} */ *uap = v;
- int error = 0;
-
- switch(SCARG(uap, op)) {
-#ifdef USER_LDT
- case I386_GET_LDT:
- error = i386_get_ldt(p, SCARG(uap, parms), retval);
- break;
-
- case I386_SET_LDT:
- error = i386_set_ldt(p, SCARG(uap, parms), retval);
- break;
-#endif
+ struct sysent const *sy;
+ register_t args[8];
+ int error;
+ int (*call) __P((struct proc *, void *, register_t *));
- case I386_IOPL:
- error = i386_iopl(p, SCARG(uap, parms), retval);
- break;
-
- case I386_GET_IOPERM:
- error = i386_get_ioperm(p, SCARG(uap, parms), retval);
- break;
-
- case I386_SET_IOPERM:
- error = i386_set_ioperm(p, SCARG(uap, parms), retval);
- break;
-
- default:
- error = EINVAL;
- break;
- }
- return (error);
+ call = sys_nosys;
+ if (SCARG(uap, op) >= nsysarch_ent)
+ goto cont;
+ sy = sysarch_ent + SCARG(uap, op);
+ call = sy->sy_call;
+ if (sy->sy_argsize &&
+ (error = copyin(SCARG(uap, parms), args, sy->sy_argsize)))
+ return error;
+ cont:
+ return (call(p, args, retval));
}
--- /mnt/tmp/new/new/new/sys/arch/i386/include/sysarch.h Sat Oct 14 02:57:52 1995
+++ arch/i386/include/sysarch.h Sun Nov 5 22:38:45 1995
@@ -42,7 +42,7 @@
int i386_iopl __P((int));
int i386_get_ioperm __P((u_long *));
int i386_set_ioperm __P((u_long *));
-int sysarch __P((int, char *));
+int sysarch __P((u_int, void *));
#endif
#endif /* !_I386_SYSARCH_H_ */
--- /mnt/tmp/new/new/new/sys/arch/i386/i386/linux_machdep.c Sat Oct 14 02:56:36 1995
+++ arch/i386/i386/linux_machdep.c Sun Nov 5 22:34:35 1995
@@ -269,21 +269,12 @@
{
struct i386_get_ldt_args gl;
int error;
- caddr_t sg;
- char *parms;
-
- sg = stackgap_init(p->p_emul);
gl.start = 0;
gl.desc = SCARG(uap, ptr);
gl.num = SCARG(uap, bytecount) / sizeof(union descriptor);
- parms = stackgap_alloc(&sg, sizeof(gl));
-
- if (error = copyout(&gl, parms, sizeof(gl)))
- return (error);
-
- if (error = i386_get_ldt(p, parms, retval))
+ if (error = i386_get_ldt(p, &gl, retval))
return (error);
*retval *= sizeof(union descriptor);
@@ -316,7 +307,6 @@
struct i386_set_ldt_args sl;
int error;
caddr_t sg;
- char *parms;
if (SCARG(uap, bytecount) != sizeof(ldt_info))
return (EINVAL);
@@ -347,14 +337,10 @@
ldt_info.entry_number, ldt_info.base_addr, ldt_info.limit);
#endif
- parms = stackgap_alloc(&sg, sizeof(sl));
-
if (error = copyout(&sd, sl.desc, sizeof(sd)))
return (error);
- if (error = copyout(&sl, parms, sizeof(sl)))
- return (error);
- if (error = i386_set_ldt(p, parms, retval))
+ if (error = i386_set_ldt(p, &sl, retval))
return (error);
*retval = 0;
--- /mnt/tmp/new/new/new/sys/arch/i386/i386/svr4_machdep.c Sat Oct 14 02:56:51 1995
+++ arch/i386/i386/svr4_machdep.c Sun Nov 5 22:49:21 1995
@@ -402,8 +402,7 @@
case SVR4_SYSARCH_DSCR:
#ifdef USER_LDT
{
- struct i386_set_ldt_args sa, *sap;
- struct sys_sysarch_args ua;
+ struct i386_set_ldt_args sa;
struct svr4_ssd ssd;
union descriptor bsd;
@@ -445,23 +444,12 @@
sa.start = IDXSEL(ssd.selector);
sa.desc = stackgap_alloc(&sg, sizeof(union descriptor));
sa.num = 1;
- sap = stackgap_alloc(&sg,
- sizeof(struct i386_set_ldt_args));
-
- if ((error = copyout(&sa, sap, sizeof(sa))) != 0) {
- printf("Cannot copyout args\n");
- return error;
- }
-
- SCARG(&ua, op) = I386_SET_LDT;
- SCARG(&ua, parms) = (char *) sap;
-
if ((error = copyout(&bsd, sa.desc, sizeof(bsd))) != 0) {
printf("Cannot copyout desc\n");
return error;
}
- return sys_sysarch(p, &ua, retval);
+ return i386_set_ldt(p, &sa, retval);
}
#endif