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