summaryrefslogtreecommitdiff
path: root/usr/src/uts/i86pc/os
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/i86pc/os')
-rw-r--r--usr/src/uts/i86pc/os/mlsetup.c17
-rw-r--r--usr/src/uts/i86pc/os/trap.c39
2 files changed, 35 insertions, 21 deletions
diff --git a/usr/src/uts/i86pc/os/mlsetup.c b/usr/src/uts/i86pc/os/mlsetup.c
index 5118e61495..02326001f2 100644
--- a/usr/src/uts/i86pc/os/mlsetup.c
+++ b/usr/src/uts/i86pc/os/mlsetup.c
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -296,23 +296,12 @@ mlsetup(struct regs *rp)
CPU->cpu_pri = 12; /* initial PIL for the boot CPU */
- CPU->cpu_ldt = ldt0_default; /* default LDT */
CPU->cpu_gdt = gdt0;
/*
- * This must be done _after_ init_tables(), called above, has set up
- * ldt0_default_desc.
+ * The kernel doesn't use LDTs unless a process explicitly requests one.
*/
-#if defined(__amd64)
- /*
- * ldt0_default64 contains all invalid entries. We use that as p0's LDT
- * because p0 should never have any reason to use the LDT. This will
- * catch things early if such a scenario should ever occur.
- */
- p0.p_ldt_desc = ldt0_default64_desc;
-#else
- p0.p_ldt_desc = ldt0_default_desc;
-#endif /* __amd64 */
+ p0.p_ldt_desc = zero_sdesc;
/*
* Kernel IDT.
diff --git a/usr/src/uts/i86pc/os/trap.c b/usr/src/uts/i86pc/os/trap.c
index 7016be0cb2..2287b59493 100644
--- a/usr/src/uts/i86pc/os/trap.c
+++ b/usr/src/uts/i86pc/os/trap.c
@@ -21,7 +21,7 @@
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -993,14 +993,39 @@ trap(struct regs *rp, caddr_t addr, processorid_t cpuid)
if (kern_gpfault(rp))
(void) die(type, rp, addr, cpuid);
goto cleanup;
+ /*FALLTHROUGH*/
+/*
+ * ONLY 32-bit PROCESSES can USE a PRIVATE LDT! 64-bit apps should have
+ * no legacy need for them, so we put a stop to it here.
+ *
+ * So: not-present fault is ONLY valid for 32-bit processes with a private LDT
+ * trying to do a system call. Emulate it.
+ *
+ * #gp fault is ONLY valid for 32-bit processes also, which DO NOT have private
+ * LDT, and are trying to do a system call. Emulate it.
+ */
case T_SEGFLT + USER: /* segment not present fault */
+ case T_GPFLT + USER: /* general protection violation */
#ifdef _SYSCALL32_IMPL
+ if (p->p_model != DATAMODEL_NATIVE) {
+#endif /* _SYSCALL32_IMPL */
if (instr_is_syscall((caddr_t)rp->r_pc)) {
+ if (type == T_SEGFLT + USER)
+ ASSERT(p->p_ldt != NULL);
+
+ if ((p->p_ldt == NULL && type == T_GPFLT + USER) ||
+ type == T_SEGFLT + USER) {
+
+ /*
+ * The user attempted a system call via the obsolete
+ * call gate mechanism. Because the process doesn't have
+ * an LDT (i.e. the ldtr contains 0), a #gp results.
+ * Emulate the syscall here, just as we do above for a
+ * #np trap.
+ */
+
/*
- * System calls via the call gate come in through
- * not-present traps.
- *
* Since this is a not-present trap, rp->r_pc points to
* the trapping lcall instruction. We need to bump it
* to the next insn so the app can continue on.
@@ -1017,11 +1042,11 @@ trap(struct regs *rp, caddr_t addr, processorid_t cpuid)
dosyscall();
goto out;
+ }
+ }
+#ifdef _SYSCALL32_IMPL
}
#endif /* _SYSCALL32_IMPL */
- /*FALLTHROUGH*/
-
- case T_GPFLT + USER: /* general protection violation */
/*
* If the current process is using a private LDT and the
* trapping instruction is sysenter, the sysenter instruction