Example #1
0
static int
db_gs(struct db_variable *vp, db_expr_t *valuep, int op)
{

	if (op == DB_VAR_GET)
		*valuep = rgs();
	else
		load_gs(*valuep);
	return (1);
}
Example #2
0
/*
 * exec_setregs may initialize some registers differently than Linux
 * does, thus potentially confusing Linux binaries. If necessary, we
 * override the exec_setregs default(s) here.
 */
static void
exec_linux_setregs(struct thread *td, struct image_params *imgp, u_long stack)
{
	struct pcb *pcb = td->td_pcb;

	exec_setregs(td, imgp, stack);

	/* Linux sets %gs to 0, we default to _udatasel */
	pcb->pcb_gs = 0;
	load_gs(0);

	pcb->pcb_initial_npxcw = __LINUX_NPXCW__;
}
Example #3
0
void
cpu_setregs(void)
{
#if 0
    unsigned int cr0;

    cr0 = rcr0();
    cr0 |= CR0_NE;			/* Done by npxinit() */
    cr0 |= CR0_MP | CR0_TS;		/* Done at every execve() too. */
    cr0 |= CR0_WP | CR0_AM;
    load_cr0(cr0);
    load_gs(_udatasel);
#endif
}
Example #4
0
static int
db_gs(struct db_variable *vp, db_expr_t *valuep, int op)
{
	struct trapframe_vm86 *tfp;

	if (kdb_frame != NULL && kdb_frame->tf_eflags & PSL_VM) {
		tfp = (void *)kdb_frame;
		if (op == DB_VAR_GET)
			*valuep = tfp->tf_vm86_gs;
		else
			tfp->tf_vm86_gs = *valuep;
		return (1);
	}
	if (op == DB_VAR_GET)
		*valuep = rgs();
	else
		load_gs(*valuep);
	return (1);
}
Example #5
0
/*
 *  All traps come here.  It is slower to have all traps call trap()
 *  rather than directly vectoring the handler.  However, this avoids a
 *  lot of code duplication and possible bugs.  The only exception is
 *  VectorSYSCALL.
 *  Trap is called with interrupts disabled via interrupt-gates.
 */
void
trap(Ureg* ureg)
{
	int clockintr, i, vno, user;
	char buf[ERRMAX];
	Vctl *ctl, *v;
	Mach *mach;

	if(!trapinited){
		/* fault386 can give a better error message */
		if(ureg->trap == VectorPF)
			fault386(ureg, nil);
		panic("trap %lud: not ready", ureg->trap);
	}

	m->perf.intrts = perfticks();
	user = userureg(ureg);
	if(user){
		up->dbgreg = ureg;
		cycles(&up->kentry);
	}

	clockintr = 0;

	vno = ureg->trap;
	if(ctl = vctl[vno]){
		if(ctl->isintr){
			m->intr++;
			if(vno >= VectorPIC && vno != VectorSYSCALL)
				m->lastintr = ctl->irq;
		}

		if(ctl->isr)
			ctl->isr(vno);
		for(v = ctl; v != nil; v = v->next){
			if(v->f)
				v->f(ureg, v->a);
		}
		if(ctl->eoi)
			ctl->eoi(vno);

		if(ctl->isintr){
			intrtime(m, vno);

			if(ctl->irq == IrqCLOCK || ctl->irq == IrqTIMER)
				clockintr = 1;

			if(up && !clockintr)
				preempted();
		}
	}
	else if(vno < nelem(excname) && user){
		spllo();
		sprint(buf, "sys: trap: %s", excname[vno]);
		postnote(up, 1, buf, NDebug);
	}
	else if(vno >= VectorPIC && vno != VectorSYSCALL){
		/*
		 * An unknown interrupt.
		 * Check for a default IRQ7. This can happen when
		 * the IRQ input goes away before the acknowledge.
		 * In this case, a 'default IRQ7' is generated, but
		 * the corresponding bit in the ISR isn't set.
		 * In fact, just ignore all such interrupts.
		 */

		/* call all interrupt routines, just in case */
		for(i = VectorPIC; i <= MaxIrqLAPIC; i++){
			ctl = vctl[i];
			if(ctl == nil)
				continue;
			if(!ctl->isintr)
				continue;
			for(v = ctl; v != nil; v = v->next){
				if(v->f)
					v->f(ureg, v->a);
			}
			/* should we do this? */
			if(ctl->eoi)
				ctl->eoi(i);
		}

		/* clear the interrupt */
		i8259isr(vno);

		if(0)print("cpu%d: spurious interrupt %d, last %d\n",
			m->machno, vno, m->lastintr);
		if(0)if(conf.nmach > 1){
			for(i = 0; i < 32; i++){
				if(!(active.machs & (1<<i)))
					continue;
				mach = MACHP(i);
				if(m->machno == mach->machno)
					continue;
				print(" cpu%d: last %d",
					mach->machno, mach->lastintr);
			}
			print("\n");
		}
		m->spuriousintr++;
		if(user)
			kexit(ureg);
		return;
	}
	else{
		if(vno == VectorNMI){
			/*
			 * Don't re-enable, it confuses the crash dumps.
			nmienable();
			 */
			iprint("cpu%d: nmi PC %#8.8lux, status %ux\n",
				m->machno, ureg->pc, inb(0x61));
			while(m->machno != 0)
				;
		}

		if(!user){
			void (*pc)(void);
			ulong *sp; 

			extern void _forkretpopgs(void);
			extern void _forkretpopfs(void);
			extern void _forkretpopes(void);
			extern void _forkretpopds(void);
			extern void _forkretiret(void);
			extern void _rdmsrinst(void);
			extern void _wrmsrinst(void);

			extern void load_fs(ulong);
			extern void load_gs(ulong);

			load_fs(NULLSEL);
			load_gs(NULLSEL);

			sp = (ulong*)&ureg->sp;	/* kernel stack */
			pc = (void*)ureg->pc;

			if(pc == _forkretpopgs || pc == _forkretpopfs || 
			   pc == _forkretpopes || pc == _forkretpopds){
				if(vno == VectorGPF || vno == VectorSNP){
					sp[0] = NULLSEL;
					return;
				}
			} else if(pc == _forkretiret){
				if(vno == VectorGPF || vno == VectorSNP){
					sp[1] = UESEL;	/* CS */
					sp[4] = UDSEL;	/* SS */
					return;
				}
			} else if(pc == _rdmsrinst || pc == _wrmsrinst){
				if(vno == VectorGPF){
					ureg->bp = -1;
					ureg->pc += 2;
					return;
				}
			}
		}

		dumpregs(ureg);
		if(!user){
			ureg->sp = (ulong)&ureg->sp;
			_dumpstack(ureg);
		}
		if(vno < nelem(excname))
			panic("%s", excname[vno]);
		panic("unknown trap/intr: %d", vno);
	}
	splhi();

	/* delaysched set because we held a lock or because our quantum ended */
	if(up && up->delaysched && clockintr){
		sched();
		splhi();
	}

	if(user){
		if(up->procctl || up->nnote)
			notify(ureg);
		kexit(ureg);
	}
}