PERFORCE change 28113 for review

Peter Wemm peter at FreeBSD.org
Fri Apr 4 18:01:17 PST 2003


http://perforce.freebsd.org/chv.cgi?CH=28113

Change 28113 by peter at peter_daintree on 2003/04/04 18:01:12

	Steer well clear of user LDT, debug regs, and 4.x hammer binaries.

Affected files ...

.. //depot/projects/hammer/sys/x86_64/x86_64/machdep.c#31 edit

Differences ...

==== //depot/projects/hammer/sys/x86_64/x86_64/machdep.c#31 (text+ko) ====

@@ -179,11 +179,6 @@
 
 int cold = 1;
 
-#ifdef COMPAT_FREEBSD4
-static void freebsd4_sendsig(sig_t catcher, int sig, sigset_t *mask,
-    u_long code);
-#endif
-
 long Maxmem = 0;
 
 vm_paddr_t phys_avail[10];
@@ -258,127 +253,6 @@
  * frame pointer, it returns to the user
  * specified pc, psl.
  */
-#ifdef COMPAT_FREEBSD4
-static void
-freebsd4_sendsig(catcher, sig, mask, code)
-	sig_t catcher;
-	int sig;
-	sigset_t *mask;
-	u_long code;
-{
-	struct sigframe4 sf, *sfp;
-	struct proc *p;
-	struct thread *td;
-	struct sigacts *psp;
-	struct trapframe *regs;
-	int oonstack;
-
-	td = curthread;
-	p = td->td_proc;
-	PROC_LOCK_ASSERT(p, MA_OWNED);
-	psp = p->p_sigacts;
-	regs = td->td_frame;
-	oonstack = sigonstack(regs->tf_esp);
-
-	/* Save user context. */
-	bzero(&sf, sizeof(sf));
-	sf.sf_uc.uc_sigmask = *mask;
-	sf.sf_uc.uc_stack = p->p_sigstk;
-	sf.sf_uc.uc_stack.ss_flags = (p->p_flag & P_ALTSTACK)
-	    ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE;
-	sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0;
-	sf.sf_uc.uc_mcontext.mc_gs = rgs();
-	bcopy(regs, &sf.sf_uc.uc_mcontext.mc_fs, sizeof(*regs));
-
-	/* Allocate space for the signal handler context. */
-	if ((p->p_flag & P_ALTSTACK) != 0 && !oonstack &&
-	    SIGISMEMBER(psp->ps_sigonstack, sig)) {
-		sfp = (struct sigframe4 *)(p->p_sigstk.ss_sp +
-		    p->p_sigstk.ss_size - sizeof(struct sigframe4));
-#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
-		p->p_sigstk.ss_flags |= SS_ONSTACK;
-#endif
-	} else
-		sfp = (struct sigframe4 *)regs->tf_esp - 1;
-	PROC_UNLOCK(p);
-
-	/* Translate the signal if appropriate. */
-	if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
-		sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
-
-	/* Build the argument list for the signal handler. */
-	sf.sf_signum = sig;
-	sf.sf_ucontext = (register_t)&sfp->sf_uc;
-	PROC_LOCK(p);
-	if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) {
-		/* Signal handler installed with SA_SIGINFO. */
-		sf.sf_siginfo = (register_t)&sfp->sf_si;
-		sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher;
-
-		/* Fill in POSIX parts */
-		sf.sf_si.si_signo = sig;
-		sf.sf_si.si_code = code;
-		sf.sf_si.si_addr = (void *)regs->tf_err;
-	} else {
-		/* Old FreeBSD-style arguments. */
-		sf.sf_siginfo = code;
-		sf.sf_addr = regs->tf_err;
-		sf.sf_ahu.sf_handler = catcher;
-	}
-	PROC_UNLOCK(p);
-
-	/*
-	 * If we're a vm86 process, we want to save the segment registers.
-	 * We also change eflags to be our emulated eflags, not the actual
-	 * eflags.
-	 */
-	if (regs->tf_eflags & PSL_VM) {
-		struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
-		struct vm86_kernel *vm86 = &td->td_pcb->pcb_ext->ext_vm86;
-
-		sf.sf_uc.uc_mcontext.mc_gs = tf->tf_vm86_gs;
-		sf.sf_uc.uc_mcontext.mc_fs = tf->tf_vm86_fs;
-		sf.sf_uc.uc_mcontext.mc_es = tf->tf_vm86_es;
-		sf.sf_uc.uc_mcontext.mc_ds = tf->tf_vm86_ds;
-
-		if (vm86->vm86_has_vme == 0)
-			sf.sf_uc.uc_mcontext.mc_eflags =
-			    (tf->tf_eflags & ~(PSL_VIF | PSL_VIP)) |
-			    (vm86->vm86_eflags & (PSL_VIF | PSL_VIP));
-
-		/*
-		 * Clear PSL_NT to inhibit T_TSSFLT faults on return from
-		 * syscalls made by the signal handler.  This just avoids
-		 * wasting time for our lazy fixup of such faults.  PSL_NT
-		 * does nothing in vm86 mode, but vm86 programs can set it
-		 * almost legitimately in probes for old cpu types.
-		 */
-		tf->tf_eflags &= ~(PSL_VM | PSL_NT | PSL_VIF | PSL_VIP);
-	}
-
-	/*
-	 * Copy the sigframe out to the user's stack.
-	 */
-	if (copyout(&sf, sfp, sizeof(*sfp)) != 0) {
-#ifdef DEBUG
-		printf("process %ld has trashed its stack\n", (long)p->p_pid);
-#endif
-		PROC_LOCK(p);
-		sigexit(td, SIGILL);
-	}
-
-	regs->tf_esp = (int)sfp;
-	regs->tf_eip = PS_STRINGS - szfreebsd4_sigcode;
-	regs->tf_eflags &= ~PSL_T;
-	regs->tf_cs = _ucodesel;
-	regs->tf_ds = _udatasel;
-	regs->tf_es = _udatasel;
-	regs->tf_fs = _udatasel;
-	regs->tf_ss = _udatasel;
-	PROC_LOCK(p);
-}
-#endif	/* COMPAT_FREEBSD4 */
-
 void
 sendsig(catcher, sig, mask, code)
 	sig_t catcher;
@@ -398,12 +272,6 @@
 	p = td->td_proc;
 	PROC_LOCK_ASSERT(p, MA_OWNED);
 	psp = p->p_sigacts;
-#ifdef COMPAT_FREEBSD4
-	if (SIGISMEMBER(psp->ps_freebsd4, sig)) {
-		freebsd4_sendsig(catcher, sig, mask, code);
-		return;
-	}
-#endif
 	regs = td->td_frame;
 	oonstack = sigonstack(regs->tf_esp);
 
@@ -492,117 +360,6 @@
  *
  * MPSAFE
  */
-#ifdef COMPAT_FREEBSD4
-/*
- * MPSAFE
- */
-int
-freebsd4_sigreturn(td, uap)
-	struct thread *td;
-	struct freebsd4_sigreturn_args /* {
-		const ucontext4 *sigcntxp;
-	} */ *uap;
-{
-	struct ucontext4 uc;
-	struct proc *p = td->td_proc;
-	struct trapframe *regs;
-	const struct ucontext4 *ucp;
-	int cs, eflags, error;
-
-	error = copyin(uap->sigcntxp, &uc, sizeof(uc));
-	if (error != 0)
-		return (error);
-	ucp = &uc;
-	regs = td->td_frame;
-	eflags = ucp->uc_mcontext.mc_eflags;
-	if (eflags & PSL_VM) {
-		struct trapframe_vm86 *tf = (struct trapframe_vm86 *)regs;
-		struct vm86_kernel *vm86;
-
-		/*
-		 * if pcb_ext == 0 or vm86_inited == 0, the user hasn't
-		 * set up the vm86 area, and we can't enter vm86 mode.
-		 */
-		if (td->td_pcb->pcb_ext == 0)
-			return (EINVAL);
-		vm86 = &td->td_pcb->pcb_ext->ext_vm86;
-		if (vm86->vm86_inited == 0)
-			return (EINVAL);
-
-		/* Go back to user mode if both flags are set. */
-		if ((eflags & PSL_VIP) && (eflags & PSL_VIF))
-			trapsignal(td, SIGBUS, 0);
-
-		if (vm86->vm86_has_vme) {
-			eflags = (tf->tf_eflags & ~VME_USERCHANGE) |
-			    (eflags & VME_USERCHANGE) | PSL_VM;
-		} else {
-			vm86->vm86_eflags = eflags;	/* save VIF, VIP */
-			eflags = (tf->tf_eflags & ~VM_USERCHANGE) |
-			    (eflags & VM_USERCHANGE) | PSL_VM;
-		}
-		bcopy(&ucp->uc_mcontext.mc_fs, tf, sizeof(struct trapframe));
-		tf->tf_eflags = eflags;
-		tf->tf_vm86_ds = tf->tf_ds;
-		tf->tf_vm86_es = tf->tf_es;
-		tf->tf_vm86_fs = tf->tf_fs;
-		tf->tf_vm86_gs = ucp->uc_mcontext.mc_gs;
-		tf->tf_ds = _udatasel;
-		tf->tf_es = _udatasel;
-		tf->tf_fs = _udatasel;
-	} else {
-		/*
-		 * Don't allow users to change privileged or reserved flags.
-		 */
-		/*
-		 * XXX do allow users to change the privileged flag PSL_RF.
-		 * The cpu sets PSL_RF in tf_eflags for faults.  Debuggers
-		 * should sometimes set it there too.  tf_eflags is kept in
-		 * the signal context during signal handling and there is no
-		 * other place to remember it, so the PSL_RF bit may be
-		 * corrupted by the signal handler without us knowing.
-		 * Corruption of the PSL_RF bit at worst causes one more or
-		 * one less debugger trap, so allowing it is fairly harmless.
-		 */
-		if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_eflags & ~PSL_RF)) {
-			printf("freebsd4_sigreturn: eflags = 0x%x\n", eflags);
-	    		return (EINVAL);
-		}
-
-		/*
-		 * Don't allow users to load a valid privileged %cs.  Let the
-		 * hardware check for invalid selectors, excess privilege in
-		 * other selectors, invalid %eip's and invalid %esp's.
-		 */
-		cs = ucp->uc_mcontext.mc_cs;
-		if (!CS_SECURE(cs)) {
-			printf("freebsd4_sigreturn: cs = 0x%x\n", cs);
-			trapsignal(td, SIGBUS, T_PROTFLT);
-			return (EINVAL);
-		}
-
-		bcopy(&ucp->uc_mcontext.mc_fs, regs, sizeof(*regs));
-	}
-
-	PROC_LOCK(p);
-#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
-	if (ucp->uc_mcontext.mc_onstack & 1)
-		p->p_sigstk.ss_flags |= SS_ONSTACK;
-	else
-		p->p_sigstk.ss_flags &= ~SS_ONSTACK;
-#endif
-
-	td->td_sigmask = ucp->uc_sigmask;
-	SIG_CANTMASK(td->td_sigmask);
-	signotify(td);
-	PROC_UNLOCK(p);
-	return (EJUSTRETURN);
-}
-#endif	/* COMPAT_FREEBSD4 */
-
-/*
- * MPSAFE
- */
 int
 sigreturn(td, uap)
 	struct thread *td;
@@ -759,9 +516,6 @@
 	pcb->pcb_gs = _udatasel;
 	load_gs(_udatasel);
 
-	if (td->td_proc->p_md.md_ldt)
-		user_ldt_free(td);
-  
 	bzero((char *)regs, sizeof(struct trapframe));
 	regs->tf_eip = entry;
 	regs->tf_esp = stack;
@@ -775,28 +529,6 @@
 	/* PS_STRINGS value for BSD/OS binaries.  It is 0 for non-BSD/OS. */
 	regs->tf_ebx = ps_strings;
 
-        /*
-         * Reset the hardware debug registers if they were in use.
-         * They won't have any meaning for the newly exec'd process.  
-         */
-        if (pcb->pcb_flags & PCB_DBREGS) {
-                pcb->pcb_dr0 = 0;
-                pcb->pcb_dr1 = 0;
-                pcb->pcb_dr2 = 0;
-                pcb->pcb_dr3 = 0;
-                pcb->pcb_dr6 = 0;
-                pcb->pcb_dr7 = 0;
-                if (pcb == PCPU_GET(curpcb)) {
-		        /*
-			 * Clear the debug registers on the running
-			 * CPU, otherwise they will end up affecting
-			 * the next process we switch to.
-			 */
-		        reset_dbregs();
-                }
-                pcb->pcb_flags &= ~PCB_DBREGS;
-        }
-
 	/*
 	 * Initialize the math emulator (if any) for the current process.
 	 * Actually, just clear the bit that says that the emulator has
@@ -1932,185 +1664,17 @@
 int
 fill_dbregs(struct thread *td, struct dbreg *dbregs)
 {
-	struct pcb *pcb;
 
-	if (td == NULL) {
-		dbregs->dr[0] = rdr0();
-		dbregs->dr[1] = rdr1();
-		dbregs->dr[2] = rdr2();
-		dbregs->dr[3] = rdr3();
-		dbregs->dr[4] = rdr4();
-		dbregs->dr[5] = rdr5();
-		dbregs->dr[6] = rdr6();
-		dbregs->dr[7] = rdr7();
-	} else {
-		pcb = td->td_pcb;
-		dbregs->dr[0] = pcb->pcb_dr0;
-		dbregs->dr[1] = pcb->pcb_dr1;
-		dbregs->dr[2] = pcb->pcb_dr2;
-		dbregs->dr[3] = pcb->pcb_dr3;
-		dbregs->dr[4] = 0;
-		dbregs->dr[5] = 0;
-		dbregs->dr[6] = pcb->pcb_dr6;
-		dbregs->dr[7] = pcb->pcb_dr7;
-	}
 	return (0);
 }
 
 int
 set_dbregs(struct thread *td, struct dbreg *dbregs)
 {
-	struct pcb *pcb;
-	int i;
-	u_int32_t mask1, mask2;
-
-	if (td == NULL) {
-		load_dr0(dbregs->dr[0]);
-		load_dr1(dbregs->dr[1]);
-		load_dr2(dbregs->dr[2]);
-		load_dr3(dbregs->dr[3]);
-		load_dr4(dbregs->dr[4]);
-		load_dr5(dbregs->dr[5]);
-		load_dr6(dbregs->dr[6]);
-		load_dr7(dbregs->dr[7]);
-	} else {
-		/*
-		 * Don't let an illegal value for dr7 get set.	Specifically,
-		 * check for undefined settings.  Setting these bit patterns
-		 * result in undefined behaviour and can lead to an unexpected
-		 * TRCTRAP.
-		 */
-		for (i = 0, mask1 = 0x3<<16, mask2 = 0x2<<16; i < 8; 
-		     i++, mask1 <<= 2, mask2 <<= 2)
-			if ((dbregs->dr[7] & mask1) == mask2)
-				return (EINVAL);
-		
-		pcb = td->td_pcb;
-		
-		/*
-		 * Don't let a process set a breakpoint that is not within the
-		 * process's address space.  If a process could do this, it
-		 * could halt the system by setting a breakpoint in the kernel
-		 * (if ddb was enabled).  Thus, we need to check to make sure
-		 * that no breakpoints are being enabled for addresses outside
-		 * process's address space, unless, perhaps, we were called by
-		 * uid 0.
-		 *
-		 * XXX - what about when the watched area of the user's
-		 * address space is written into from within the kernel
-		 * ... wouldn't that still cause a breakpoint to be generated
-		 * from within kernel mode?
-		 */
 
-		if (suser(td) != 0) {
-			if (dbregs->dr[7] & 0x3) {
-				/* dr0 is enabled */
-				if (dbregs->dr[0] >= VM_MAXUSER_ADDRESS)
-					return (EINVAL);
-			}
-			
-			if (dbregs->dr[7] & (0x3<<2)) {
-				/* dr1 is enabled */
-				if (dbregs->dr[1] >= VM_MAXUSER_ADDRESS)
-					return (EINVAL);
-			}
-			
-			if (dbregs->dr[7] & (0x3<<4)) {
-				/* dr2 is enabled */
-				if (dbregs->dr[2] >= VM_MAXUSER_ADDRESS)
-					return (EINVAL);
-			}
-			
-			if (dbregs->dr[7] & (0x3<<6)) {
-				/* dr3 is enabled */
-				if (dbregs->dr[3] >= VM_MAXUSER_ADDRESS)
-					return (EINVAL);
-			}
-		}
-
-		pcb->pcb_dr0 = dbregs->dr[0];
-		pcb->pcb_dr1 = dbregs->dr[1];
-		pcb->pcb_dr2 = dbregs->dr[2];
-		pcb->pcb_dr3 = dbregs->dr[3];
-		pcb->pcb_dr6 = dbregs->dr[6];
-		pcb->pcb_dr7 = dbregs->dr[7];
-
-		pcb->pcb_flags |= PCB_DBREGS;
-	}
-
 	return (0);
 }
 
-/*
- * Return > 0 if a hardware breakpoint has been hit, and the
- * breakpoint was in user space.  Return 0, otherwise.
- */
-int
-user_dbreg_trap(void)
-{
-        u_int32_t dr7, dr6; /* debug registers dr6 and dr7 */
-        u_int32_t bp;       /* breakpoint bits extracted from dr6 */
-        int nbp;            /* number of breakpoints that triggered */
-        caddr_t addr[4];    /* breakpoint addresses */
-        int i;
-        
-        dr7 = rdr7();
-        if ((dr7 & 0x000000ff) == 0) {
-                /*
-                 * all GE and LE bits in the dr7 register are zero,
-                 * thus the trap couldn't have been caused by the
-                 * hardware debug registers
-                 */
-                return 0;
-        }
-
-        nbp = 0;
-        dr6 = rdr6();
-        bp = dr6 & 0x0000000f;
-
-        if (!bp) {
-                /*
-                 * None of the breakpoint bits are set meaning this
-                 * trap was not caused by any of the debug registers
-                 */
-                return 0;
-        }
-
-        /*
-         * at least one of the breakpoints were hit, check to see
-         * which ones and if any of them are user space addresses
-         */
-
-        if (bp & 0x01) {
-                addr[nbp++] = (caddr_t)rdr0();
-        }
-        if (bp & 0x02) {
-                addr[nbp++] = (caddr_t)rdr1();
-        }
-        if (bp & 0x04) {
-                addr[nbp++] = (caddr_t)rdr2();
-        }
-        if (bp & 0x08) {
-                addr[nbp++] = (caddr_t)rdr3();
-        }
-
-        for (i=0; i<nbp; i++) {
-                if (addr[i] <
-                    (caddr_t)VM_MAXUSER_ADDRESS) {
-                        /*
-                         * addr[i] is in user space
-                         */
-                        return nbp;
-                }
-        }
-
-        /*
-         * None of the breakpoints are in user space.
-         */
-        return 0;
-}
-
-
 #ifndef DDB
 void
 Debugger(const char *msg)


More information about the p4-projects mailing list