/* ** VMX insn operates on 64 bits in long mode ** so we ensure allocation */ void __regparm__(2) __vmcs_force_read(raw64_t *val, vmcs_field_enc_t enc) { raw64_t tmp; if(!enc.fake) { vmx_insn_err_t vmx_err; if(!vmx_vmread(&vmx_err, &tmp.raw, enc.raw)) panic("vmread(0x%x) err %d\n", enc.raw, vmx_err.raw); switch(enc.fwidth) { case VMCS_FIELD_ENC_FIELD_WIDTH_16: val->raw = tmp.wlow; break; case VMCS_FIELD_ENC_FIELD_WIDTH_32: val->raw = tmp.low; break; default: val->raw = tmp.raw; break; } return; } if(val == (raw64_t*)&vm_state.cr2) vm_state.cr2.raw = get_cr2(); else if(val == (raw64_t*)&vm_state.dr6) vm_state.dr6.raw = get_dr6(); }
/* ** VMX insn operates on 64 bits in long mode ** so we ensure allocation */ void __regparm__(2) __vmcs_force_read(raw64_t *val, vmcs_field_enc_t enc) { raw64_t tmp; if(!enc.fake) { vmx_insn_err_t vmx_err; if(!vmx_vmread(&vmx_err, &tmp.raw, enc.raw)) panic("vmread(0x%x) err %d\n", enc.raw, vmx_err.raw); switch(enc.fwidth) { case VMCS_FIELD_ENC_FIELD_WIDTH_16: val->wlow = tmp.wlow; break; case VMCS_FIELD_ENC_FIELD_WIDTH_32: val->low = tmp.low; break; default: val->raw = tmp.raw; break; } /* ** don't use debug, since some fields might have not been read */ #ifdef CONFIG_VMX_ACC_DBG printf("vmread(0x%x) = 0x%X\n", enc.raw, tmp.raw); #endif return; } if(val == (raw64_t*)&vm_state.cr2) vm_state.cr2.raw = get_cr2(); else if(val == (raw64_t*)&vm_state.dr6) vm_state.dr6.raw = get_dr6(); }
boolean_t kdb_trap( int type, int code, struct i386_saved_state *regs) { spl_t s; s = splhigh(); saved_ipl[cpu_number()] = s; switch (type) { case T_DEBUG: /* single_step */ { int addr; int status = get_dr6(); if (status & 0xf) { /* hmm hdw break */ addr = status & 0x8 ? get_dr3() : status & 0x4 ? get_dr2() : status & 0x2 ? get_dr1() : get_dr0(); regs->efl |= EFL_RF; db_single_step_cmd(addr, 0, 1, "p"); } } case T_INT3: /* breakpoint */ case T_WATCHPOINT: /* watchpoint */ case -1: /* keyboard interrupt */ break; default: if (db_recover) { i386_nested_saved_state = *regs; db_printf("Caught %s (%d), code = %x, pc = %x\n", trap_name(type), type, code, regs->eip); db_error(""); /*NOTREACHED*/ } kdbprinttrap(type, code); } #if NCPUS > 1 if (db_enter()) #endif /* NCPUS > 1 */ { i386_last_saved_statep = regs; i386_last_kdb_sp = (unsigned) &type; /* XXX Should switch to ddb`s own stack here. */ ddb_regs = *regs; if ((regs->cs & 0x3) == KERNEL_RING) { /* * Kernel mode - esp and ss not saved */ ddb_regs.uesp = (int)®s->uesp; /* kernel stack pointer */ ddb_regs.ss = KERNEL_DS; } cnpollc(TRUE); db_task_trap(type, code, (regs->cs & 0x3) != 0); cnpollc(FALSE); regs->eip = ddb_regs.eip; regs->efl = ddb_regs.efl; regs->eax = ddb_regs.eax; regs->ecx = ddb_regs.ecx; regs->edx = ddb_regs.edx; regs->ebx = ddb_regs.ebx; if ((regs->cs & 0x3) != KERNEL_RING) { /* * user mode - saved esp and ss valid */ regs->uesp = ddb_regs.uesp; /* user stack pointer */ regs->ss = ddb_regs.ss & 0xffff; /* user stack segment */ } regs->ebp = ddb_regs.ebp; regs->esi = ddb_regs.esi; regs->edi = ddb_regs.edi; regs->es = ddb_regs.es & 0xffff; regs->cs = ddb_regs.cs & 0xffff; regs->ds = ddb_regs.ds & 0xffff; regs->fs = ddb_regs.fs & 0xffff; regs->gs = ddb_regs.gs & 0xffff; if ((type == T_INT3) && (db_get_task_value(regs->eip, BKPT_SIZE, FALSE, TASK_NULL) == BKPT_INST)) regs->eip += BKPT_SIZE; } #if NCPUS > 1 db_leave(); #endif /* NCPUS > 1 */ splx(s); return 1; }