Beispiel #1
0
/* handle int15 from real mode code
 * we use CS:IP for vmcall instruction to get indication that there is int15
 * check for E820 function, if true, then handle it
 * no other int15 function should come here */
boolean_t handle_int15_vmcall(guest_cpu_handle_t gcpu)
{
	uint16_t selector = 0;
	uint64_t base = 0;
	uint32_t limit = 0;
	uint32_t attr = 0;
	uint32_t expected_lnr_addr;
	uint32_t vmcall_lnr_addr;
	volatile uint64_t r_rax = 0, r_rdx = 0, r_rip = 0;

	if (!(0x1 & gcpu_get_guest_visible_control_reg(gcpu, IA32_CTRL_CR0))) {
		/* PE = 0?  then real mode
		 * need to get CS:IP to make sure that this VMCALL from INT15 handler */
		gcpu_get_segment_reg(gcpu,
			IA32_SEG_CS,
			&selector,
			&base,
			&limit,
			&attr);
		r_rip = gcpu_get_gp_reg(gcpu, IA32_REG_RIP);

		expected_lnr_addr = SEGMENT_OFFSET_TO_LINEAR(
			g_int15_trapped_page >> 16,
			g_int15_trapped_page +
			VMCALL_OFFSET);
		vmcall_lnr_addr =
			SEGMENT_OFFSET_TO_LINEAR((uint32_t)selector,
				(uint32_t)r_rip);

		/* check to see if the CS:IP is same as expected for VMCALL in INT15
		 * handler */
		if (expected_lnr_addr == vmcall_lnr_addr) {
			r_rax = gcpu_get_gp_reg(gcpu, IA32_REG_RAX);
			r_rdx = gcpu_get_gp_reg(gcpu, IA32_REG_RDX);
			if ((0xE820 == r_rax) && (SMAP == r_rdx)) {
				if (g_emap == NULL) {
					g_emap =
						mon_malloc(sizeof(
								e820_map_state_t));
					MON_ASSERT(g_emap != NULL);
					mon_memset(g_emap, 0,
						sizeof(e820_map_state_t));
				}
				e820_save_guest_state(gcpu, g_emap);
				g_emap->guest_handle = mon_gcpu_guest_handle(
					gcpu);
				e820_int15_handler(g_emap);
				e820_restore_guest_state(gcpu, g_emap);
				gcpu_skip_guest_instruction(gcpu);
				return TRUE;
			} else {
				MON_LOG(mask_anonymous,
					level_error,
					"INT15 wasn't handled for function 0x%x\n",
					r_rax);
				MON_DEADLOOP(); /* Should not get here */
				return FALSE;
			}
		}
	}
Beispiel #2
0
static
void force_ring3_ss(guest_cpu_handle_t gcpu)
{
	seg_reg_t ss;
	cr0_t cr0;
	eflags_t flags;

	cr0.value =
		(uint32_t)gcpu_get_guest_visible_control_reg(gcpu,
			IA32_CTRL_CR0);

	flags.value = (uint32_t)gcpu_get_gp_reg(gcpu, IA32_REG_RFLAGS);

	if ((cr0.bits.pe == 0) || (flags.bits.v86_mode == 1)) {
		return;
	}

	gcpu_get_segment_reg(gcpu, IA32_SEG_TR,
		(uint16_t *)&(ss.selector),
		(uint64_t *)&(ss.base),
		(uint32_t *)&(ss.limit),
		(uint32_t *)&(ss.ar));

	ss.ar.bits.dpl = 3;

	gcpu_set_segment_reg(gcpu, IA32_SEG_SS, ss.selector, ss.base,
		ss.limit, ss.ar.value);
	return;
}
Beispiel #3
0
void vmm_deadloop_dump(UINT32 file_code, UINT32 line_num)
{
#define DEFAULT_VIEW_HANDLE 0

    GUEST_CPU_HANDLE gcpu;
    EM64T_RFLAGS     rflags;
    IA32_VMX_VMCS_GUEST_INTERRUPTIBILITY  interruptibility;

    gcpu = scheduler_current_gcpu();
    if(!gcpu)
        VMM_UP_BREAKPOINT();

    report_uvmm_event(UVMM_EVENT_VMM_ASSERT, (VMM_IDENTIFICATION_DATA)gcpu, (const GUEST_VCPU*)guest_vcpu(gcpu), NULL);

    // send debug info to serial port and guest buffer
    vmm_deadloop_internal(file_code, line_num, gcpu);

        // clear interrupt flag
    rflags.Uint64 = gcpu_get_gp_reg(gcpu, IA32_REG_RFLAGS);
    rflags.Bits.IFL = 0;
    gcpu_set_gp_reg(gcpu, IA32_REG_RFLAGS, rflags.Uint64);

    interruptibility.Uint32 = gcpu_get_interruptibility_state(gcpu);
    interruptibility.Bits.BlockNextInstruction = 0;
    gcpu_set_interruptibility_state(gcpu, interruptibility.Uint32);

    // generate BSOD
    gcpu_inject_gp0(gcpu);
    gcpu_resume(gcpu);
}
Beispiel #4
0
/*
 * Copy guest status from VMCS to tss buffer.
 */
static
void copy_vmcs_to_tss32(guest_cpu_handle_t gcpu, tss32_t *tss)
{
	vmcs_object_t *vmcs = mon_gcpu_get_vmcs(gcpu);

	tss->eip = (uint32_t)gcpu_get_gp_reg(gcpu, IA32_REG_RIP);
	tss->eflags = (uint32_t)gcpu_get_gp_reg(gcpu, IA32_REG_RFLAGS);
	tss->eax = (uint32_t)gcpu_get_gp_reg(gcpu, IA32_REG_RAX);
	tss->ecx = (uint32_t)gcpu_get_gp_reg(gcpu, IA32_REG_RCX);
	tss->edx = (uint32_t)gcpu_get_gp_reg(gcpu, IA32_REG_RDX);
	tss->ebx = (uint32_t)gcpu_get_gp_reg(gcpu, IA32_REG_RBX);
	tss->esp = (uint32_t)gcpu_get_gp_reg(gcpu, IA32_REG_RSP);
	tss->ebp = (uint32_t)gcpu_get_gp_reg(gcpu, IA32_REG_RBP);
	tss->esi = (uint32_t)gcpu_get_gp_reg(gcpu, IA32_REG_RSI);
	tss->edi = (uint32_t)gcpu_get_gp_reg(gcpu, IA32_REG_RDI);

	tss->es = (uint32_t)mon_vmcs_read(vmcs, VMCS_GUEST_ES_SELECTOR);
	tss->cs = (uint32_t)mon_vmcs_read(vmcs, VMCS_GUEST_CS_SELECTOR);
	tss->ss = (uint32_t)mon_vmcs_read(vmcs, VMCS_GUEST_SS_SELECTOR);
	tss->ds = (uint32_t)mon_vmcs_read(vmcs, VMCS_GUEST_DS_SELECTOR);
	tss->fs = (uint32_t)mon_vmcs_read(vmcs, VMCS_GUEST_FS_SELECTOR);
	tss->gs = (uint32_t)mon_vmcs_read(vmcs, VMCS_GUEST_GS_SELECTOR);
}
void print_guest_gprs(GUEST_CPU_HANDLE gcpu)
{
    VMM_LOG(mask_anonymous, level_trace,"IA32_REG_RCX = %08X\n", gcpu_get_gp_reg(gcpu, IA32_REG_RCX));
    VMM_LOG(mask_anonymous, level_trace,"IA32_REG_RDX = %08X\n", gcpu_get_gp_reg(gcpu, IA32_REG_RDX));
    VMM_LOG(mask_anonymous, level_trace,"IA32_REG_RBX = %08X\n", gcpu_get_gp_reg(gcpu, IA32_REG_RBX));
    VMM_LOG(mask_anonymous, level_trace,"IA32_REG_RBP = %08X\n", gcpu_get_gp_reg(gcpu, IA32_REG_RBP));
    VMM_LOG(mask_anonymous, level_trace,"IA32_REG_RSI = %08X\n", gcpu_get_gp_reg(gcpu, IA32_REG_RSI));
    VMM_LOG(mask_anonymous, level_trace,"IA32_REG_RDI = %08X\n", gcpu_get_gp_reg(gcpu, IA32_REG_RDI));
    VMM_LOG(mask_anonymous, level_trace,"IA32_REG_R8  = %08X\n", gcpu_get_gp_reg(gcpu, IA32_REG_R8));
    VMM_LOG(mask_anonymous, level_trace,"IA32_REG_R9  = %08X\n", gcpu_get_gp_reg(gcpu, IA32_REG_R9));
    VMM_LOG(mask_anonymous, level_trace,"IA32_REG_R10 = %08X\n", gcpu_get_gp_reg(gcpu, IA32_REG_R10));
    VMM_LOG(mask_anonymous, level_trace,"IA32_REG_R11 = %08X\n", gcpu_get_gp_reg(gcpu, IA32_REG_R11));
    VMM_LOG(mask_anonymous, level_trace,"IA32_REG_R12 = %08X\n", gcpu_get_gp_reg(gcpu, IA32_REG_R12));
    VMM_LOG(mask_anonymous, level_trace,"IA32_REG_R13 = %08X\n", gcpu_get_gp_reg(gcpu, IA32_REG_R13));
    VMM_LOG(mask_anonymous, level_trace,"IA32_REG_R14 = %08X\n", gcpu_get_gp_reg(gcpu, IA32_REG_R14));
    VMM_LOG(mask_anonymous, level_trace,"IA32_REG_R15 = %08X\n", gcpu_get_gp_reg(gcpu, IA32_REG_R15));
}