Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/xen Add support for i386_iopl.



details:   https://anonhg.NetBSD.org/src/rev/089f27554988
branches:  trunk
changeset: 566034:089f27554988
user:      cl <cl%NetBSD.org@localhost>
date:      Sun Apr 25 23:46:07 2004 +0000

description:
Add support for i386_iopl.

diffstat:

 sys/arch/xen/conf/files.xen     |    4 +-
 sys/arch/xen/i386/machdep.c     |   20 +-
 sys/arch/xen/i386/sys_machdep.c |  550 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 568 insertions(+), 6 deletions(-)

diffs (truncated from 630 to 300 lines):

diff -r cd4194f01d3f -r 089f27554988 sys/arch/xen/conf/files.xen
--- a/sys/arch/xen/conf/files.xen       Sun Apr 25 23:17:59 2004 +0000
+++ b/sys/arch/xen/conf/files.xen       Sun Apr 25 23:46:07 2004 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.xen,v 1.10 2004/04/24 21:33:32 cl Exp $
+#      $NetBSD: files.xen,v 1.11 2004/04/25 23:46:07 cl Exp $
 #      NetBSD: files.x86,v 1.10 2003/10/08 17:30:00 bouyer Exp 
 #      NetBSD: files.i386,v 1.254 2004/03/25 23:32:10 jmc Exp 
 
@@ -42,7 +42,7 @@
 file   arch/xen/i386/pmap.c
 file   arch/i386/i386/process_machdep.c
 file   arch/i386/i386/procfs_machdep.c procfs
-file   arch/i386/i386/sys_machdep.c
+file   arch/xen/i386/sys_machdep.c
 file   arch/i386/i386/syscall.c
 file   arch/xen/i386/trap.c
 file   arch/i386/i386/vm_machdep.c
diff -r cd4194f01d3f -r 089f27554988 sys/arch/xen/i386/machdep.c
--- a/sys/arch/xen/i386/machdep.c       Sun Apr 25 23:17:59 2004 +0000
+++ b/sys/arch/xen/i386/machdep.c       Sun Apr 25 23:46:07 2004 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: machdep.c,v 1.5 2004/04/25 19:01:27 cl Exp $   */
+/*     $NetBSD: machdep.c,v 1.6 2004/04/25 23:46:07 cl Exp $   */
 /*     NetBSD: machdep.c,v 1.552 2004/03/24 15:34:49 atatat Exp        */
 
 /*-
@@ -73,7 +73,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.5 2004/04/25 19:01:27 cl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.6 2004/04/25 23:46:07 cl Exp $");
 
 #include "opt_beep.h"
 #include "opt_compat_ibcs2.h"
@@ -392,7 +392,8 @@
        cpu_info_primary.ci_curpcb = pcb = &lwp0.l_addr->u_pcb;
 
        pcb->pcb_tss.tss_ioopt =
-           ((caddr_t)pcb->pcb_iomap - (caddr_t)&pcb->pcb_tss) << 16;
+           ((caddr_t)pcb->pcb_iomap - (caddr_t)&pcb->pcb_tss) << 16
+               | SEL_KPL;              /* i/o pl */
 
        for (x = 0; x < sizeof(pcb->pcb_iomap) / 4; x++)
                pcb->pcb_iomap[x] = 0xffffffff;
@@ -427,7 +428,8 @@
        struct pcb *pcb = ci->ci_idle_pcb;
 
        pcb->pcb_tss.tss_ioopt =
-           ((caddr_t)pcb->pcb_iomap - (caddr_t)&pcb->pcb_tss) << 16;
+           ((caddr_t)pcb->pcb_iomap - (caddr_t)&pcb->pcb_tss) << 16
+               | SEL_KPL;              /* i/o pl */
        for (x = 0; x < sizeof(pcb->pcb_iomap) / 4; x++)
                pcb->pcb_iomap[x] = 0xffffffff;
 
@@ -445,9 +447,19 @@
 void
 i386_switch_context(struct pcb *new)
 {
+       dom0_op_t op;
+
        if (new->pcb_cr0 & CR0_TS)
                HYPERVISOR_fpu_taskswitch();
+
        HYPERVISOR_stack_switch(new->pcb_tss.tss_ss0, new->pcb_tss.tss_esp0);
+
+       if (xen_start_info.flags & SIF_PRIVILEGED) {
+               op.cmd = DOM0_IOPL;
+               op.u.iopl.domain = xen_start_info.dom_id;
+               op.u.iopl.iopl = new->pcb_tss.tss_ioopt & SEL_RPL; /* i/o pl */
+               HYPERVISOR_dom0_op(&op);
+       }
 }
 
 /*
diff -r cd4194f01d3f -r 089f27554988 sys/arch/xen/i386/sys_machdep.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/xen/i386/sys_machdep.c   Sun Apr 25 23:46:07 2004 +0000
@@ -0,0 +1,550 @@
+/*     $NetBSD: sys_machdep.c,v 1.1 2004/04/25 23:46:07 cl Exp $       */
+/*     NetBSD: sys_machdep.c,v 1.70 2003/10/27 14:11:47 junyoung Exp   */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Charles M. Hannum.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: sys_machdep.c,v 1.1 2004/04/25 23:46:07 cl Exp $");
+
+#include "opt_compat_netbsd.h"
+#include "opt_mtrr.h"
+#include "opt_perfctrs.h"
+#include "opt_user_ldt.h"
+#include "opt_vm86.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/ioctl.h>
+#include <sys/file.h>
+#include <sys/time.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+#include <sys/uio.h>
+#include <sys/kernel.h>
+#include <sys/buf.h>
+#include <sys/signal.h>
+#include <sys/malloc.h>
+
+#include <sys/mount.h>
+#include <sys/sa.h>
+#include <sys/syscallargs.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#include <machine/gdt.h>
+#include <machine/psl.h>
+#include <machine/reg.h>
+#include <machine/sysarch.h>
+#include <machine/mtrr.h>
+
+#ifdef VM86
+#include <machine/vm86.h>
+#endif
+
+#ifdef PERFCTRS
+#include <machine/pmc.h>
+#endif
+
+extern struct vm_map *kernel_map;
+
+int i386_iopl(struct lwp *, void *, register_t *);
+int i386_get_ioperm(struct lwp *, void *, register_t *);
+int i386_set_ioperm(struct lwp *, void *, register_t *);
+int i386_get_mtrr(struct lwp *, void *, register_t *);
+int i386_set_mtrr(struct lwp *, void *, register_t *);
+
+#ifdef USER_LDT
+
+#ifdef LDT_DEBUG
+static void i386_print_ldt(int, const struct segment_descriptor *);
+
+static void
+i386_print_ldt(i, d)
+       int  i;
+       const struct segment_descriptor *d;
+{
+       printf("[%d] lolimit=0x%x, lobase=0x%x, type=%u, dpl=%u, p=%u, "
+           "hilimit=0x%x, xx=%x, def32=%u, gran=%u, hibase=0x%x\n",
+           i, d->sd_lolimit, d->sd_lobase, d->sd_type, d->sd_dpl, d->sd_p,
+           d->sd_hilimit, d->sd_xx, d->sd_def32, d->sd_gran, d->sd_hibase);
+}
+#endif
+
+int
+i386_get_ldt(l, args, retval)
+       struct lwp *l;
+       void *args;
+       register_t *retval;
+{
+       int error;
+       struct proc *p = l->l_proc;
+       pmap_t pmap = p->p_vmspace->vm_map.pmap;
+       int nldt, num;
+       union descriptor *lp, *cp;
+       struct i386_get_ldt_args ua;
+
+       if ((error = copyin(args, &ua, sizeof(ua))) != 0)
+               return (error);
+
+#ifdef LDT_DEBUG
+       printf("i386_get_ldt: start=%d num=%d descs=%p\n", ua.start,
+           ua.num, ua.desc);
+#endif
+
+       if (ua.start < 0 || ua.num < 0 || ua.start > 8192 || ua.num > 8192 ||
+           ua.start + ua.num > 8192)
+               return (EINVAL);
+
+       cp = malloc(ua.num * sizeof(union descriptor), M_TEMP, M_WAITOK);
+       if (cp == NULL)
+               return ENOMEM;
+
+       simple_lock(&pmap->pm_lock);
+
+       if (pmap->pm_flags & PMF_USER_LDT) {
+               nldt = pmap->pm_ldt_len;
+               lp = pmap->pm_ldt;
+       } else {
+               nldt = NLDT;
+               lp = ldt;
+       }
+
+       if (ua.start > nldt) {
+               simple_unlock(&pmap->pm_lock);
+               free(cp, M_TEMP);
+               return (EINVAL);
+       }
+
+       lp += ua.start;
+       num = min(ua.num, nldt - ua.start);
+#ifdef LDT_DEBUG
+       {
+               int i;
+               for (i = 0; i < num; i++)
+                       i386_print_ldt(i, &lp[i].sd);
+       }
+#endif
+
+       memcpy(cp, lp, num * sizeof(union descriptor));
+       simple_unlock(&pmap->pm_lock);
+
+       error = copyout(cp, ua.desc, num * sizeof(union descriptor));
+       if (error == 0)
+               *retval = num;
+
+       free(cp, M_TEMP);
+       return (error);
+}
+
+int
+i386_set_ldt(l, args, retval)
+       struct lwp *l;
+       void *args;
+       register_t *retval;
+{
+       int error, i, n;
+       struct proc *p = l->l_proc;
+       struct pcb *pcb = &l->l_addr->u_pcb;
+       pmap_t pmap = p->p_vmspace->vm_map.pmap;
+       struct i386_set_ldt_args ua;
+       union descriptor *descv;
+       size_t old_len, new_len, ldt_len;
+       union descriptor *old_ldt, *new_ldt;
+
+       if ((error = copyin(args, &ua, sizeof(ua))) != 0)
+               return (error);
+
+       if (ua.start < 0 || ua.num < 0 || ua.start > 8192 || ua.num > 8192 ||
+           ua.start + ua.num > 8192)
+               return (EINVAL);
+
+       descv = malloc(sizeof (*descv) * ua.num, M_TEMP, M_NOWAIT);
+       if (descv == NULL)
+               return (ENOMEM);
+
+       if ((error = copyin(ua.desc, descv, sizeof (*descv) * ua.num)) != 0)
+               goto out;
+
+       /* Check descriptors for access violations. */
+       for (i = 0; i < ua.num; i++) {
+               union descriptor *desc = &descv[i];
+
+               switch (desc->sd.sd_type) {
+               case SDT_SYSNULL:
+                       desc->sd.sd_p = 0;
+                       break;
+               case SDT_SYS286CGT:
+               case SDT_SYS386CGT:
+                       /*
+                        * Only allow call gates targeting a segment
+                        * in the LDT or a user segment in the fixed
+                        * part of the gdt.  Segments in the LDT are
+                        * constrained (below) to be user segments.
+                        */
+                       if (desc->gd.gd_p != 0 &&



Home | Main Index | Thread Index | Old Index