FreeBSD/lib/libvmmapi/vmmapi_freebsd.c
/*
 * Setup the 'vcpu' register set such that it will begin execution at
 * 'eip' in flat mode.
 */
Setup the 'vcpu' register set such that it will begin execution at
'eip' in flat mode.
Setup the ' vcpu ' register set such that it will begin execution at ' eip ' in flat mode .
int
vm_setup_freebsd_registers_i386(struct vmctx *vmctx, int vcpu, uint32_t eip,
				uint32_t gdtbase, uint32_t esp)
{
	uint64_t cr0, rflags, desc_base;
	uint32_t desc_access, desc_limit, tssbase;
	uint16_t gsel;
	struct segment_descriptor *gdt;
	int error, tmp;
	error = vm_get_capability(vmctx, vcpu, VM_CAP_UNRESTRICTED_GUEST, &tmp);
	if (error)
		goto done;
	error = vm_set_capability(vmctx, vcpu, VM_CAP_UNRESTRICTED_GUEST, 1);
	if (error)
		goto done;
	cr0 = CR0_PE | CR0_NE;
	if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_CR0, cr0)) != 0)
		goto done;
	if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_CR4, 0)) != 0)
		goto done;
	if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_EFER, 0)))
		goto done;
	gdt = vm_map_gpa(vmctx, gdtbase, 0x1000);
	if (gdt == NULL)
		return (EFAULT);
	memcpy(gdt, i386_gdt, sizeof(i386_gdt));
	desc_base = gdtbase;
	desc_limit = sizeof(i386_gdt) - 1;
	error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_GDTR,
			    desc_base, desc_limit, 0);
	if (error != 0)
		goto done;
	tssbase = gdtbase + 0x1000;
	gdt[3].sd_lobase = tssbase;	
	rflags = 0x2;
	error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RFLAGS, rflags);
	if (error)
		goto done;
	desc_base = 0;
	desc_limit = 0xffffffff;
	desc_access = DESC_GRAN | DESC_DEF32 | DESC_PRESENT | SDT_MEMERA;
	error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_CS,
			    desc_base, desc_limit, desc_access);
	desc_access = DESC_GRAN | DESC_DEF32 | DESC_PRESENT | SDT_MEMRWA;
	error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_DS,
			    desc_base, desc_limit, desc_access);
	if (error)
		goto done;
	error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_ES,
			    desc_base, desc_limit, desc_access);
	if (error)
		goto done;
	error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_FS,
			    desc_base, desc_limit, desc_access);
	if (error)
		goto done;
	error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_GS,
			    desc_base, desc_limit, desc_access);
	if (error)
		goto done;
	error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_SS,
			    desc_base, desc_limit, desc_access);
	if (error)
		goto done;
	desc_base = tssbase;
	desc_limit = I386_TSS_SIZE - 1;
	desc_access = DESC_PRESENT | SDT_SYS386BSY;
	error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_TR,
			    desc_base, desc_limit, desc_access);
	if (error)
		goto done;
	error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_LDTR, 0, 0,
			    DESC_UNUSABLE);
	if (error)
		goto done;
	gsel = GSEL(GUEST_CODE_SEL, SEL_KPL);
	if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_CS, gsel)) != 0)
		goto done;
	gsel = GSEL(GUEST_DATA_SEL, SEL_KPL);
	if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_DS, gsel)) != 0)
		goto done;
	if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_ES, gsel)) != 0)
		goto done;
	if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_FS, gsel)) != 0)
		goto done;
	if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_GS, gsel)) != 0)
		goto done;
	if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_SS, gsel)) != 0)
		goto done;
	gsel = GSEL(GUEST_TSS_SEL, SEL_KPL);
	if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_TR, gsel)) != 0)
		goto done;
	if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_LDTR, 0)) != 0)
		goto done;
	if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RIP, eip)) != 0)
		goto done;
	if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RSP, esp)) != 0)
		goto done;
	error = 0;
done:
	return (error);
}
int vm_setup_freebsd_registers_i386 ( struct vmctx * vmctx , int vcpu , uint32_t eip , uint32_t gdtbase , uint32_t esp ) { uint64_t cr0 , rflags , desc_base ; uint32_t desc_access , desc_limit , tssbase ; uint16_t gsel ; struct segment_descriptor * gdt ; int error , tmp ; error = vm_get_capability ( vmctx , vcpu , VM_CAP_UNRESTRICTED_GUEST , & tmp ) ; if ( error ) goto done ; error = vm_set_capability ( vmctx , vcpu , VM_CAP_UNRESTRICTED_GUEST , 1 ) ; if ( error ) goto done ; cr0 = CR0_PE | CR0_NE ; if ( ( error = vm_set_register ( vmctx , vcpu , VM_REG_GUEST_CR0 , cr0 ) ) != 0 ) goto done ; if ( ( error = vm_set_register ( vmctx , vcpu , VM_REG_GUEST_CR4 , 0 ) ) != 0 ) goto done ; if ( ( error = vm_set_register ( vmctx , vcpu , VM_REG_GUEST_EFER , 0 ) ) ) goto done ; gdt = vm_map_gpa ( vmctx , gdtbase , 0x1000 ) ; if ( gdt == NULL ) return ( EFAULT ) ; memcpy ( gdt , i386_gdt , sizeof ( i386_gdt ) ) ; desc_base = gdtbase ; desc_limit = sizeof ( i386_gdt ) - 1 ; error = vm_set_desc ( vmctx , vcpu , VM_REG_GUEST_GDTR , desc_base , desc_limit , 0 ) ; if ( error != 0 ) goto done ; tssbase = gdtbase + 0x1000 ; gdt [ 3 ] . sd_lobase = tssbase ; rflags = 0x2 ; error = vm_set_register ( vmctx , vcpu , VM_REG_GUEST_RFLAGS , rflags ) ; if ( error ) goto done ; desc_base = 0 ; desc_limit = 0xffffffff ; desc_access = DESC_GRAN | DESC_DEF32 | DESC_PRESENT | SDT_MEMERA ; error = vm_set_desc ( vmctx , vcpu , VM_REG_GUEST_CS , desc_base , desc_limit , desc_access ) ; desc_access = DESC_GRAN | DESC_DEF32 | DESC_PRESENT | SDT_MEMRWA ; error = vm_set_desc ( vmctx , vcpu , VM_REG_GUEST_DS , desc_base , desc_limit , desc_access ) ; if ( error ) goto done ; error = vm_set_desc ( vmctx , vcpu , VM_REG_GUEST_ES , desc_base , desc_limit , desc_access ) ; if ( error ) goto done ; error = vm_set_desc ( vmctx , vcpu , VM_REG_GUEST_FS , desc_base , desc_limit , desc_access ) ; if ( error ) goto done ; error = vm_set_desc ( vmctx , vcpu , VM_REG_GUEST_GS , desc_base , desc_limit , desc_access ) ; if ( error ) goto done ; error = vm_set_desc ( vmctx , vcpu , VM_REG_GUEST_SS , desc_base , desc_limit , desc_access ) ; if ( error ) goto done ; desc_base = tssbase ; desc_limit = I386_TSS_SIZE - 1 ; desc_access = DESC_PRESENT | SDT_SYS386BSY ; error = vm_set_desc ( vmctx , vcpu , VM_REG_GUEST_TR , desc_base , desc_limit , desc_access ) ; if ( error ) goto done ; error = vm_set_desc ( vmctx , vcpu , VM_REG_GUEST_LDTR , 0 , 0 , DESC_UNUSABLE ) ; if ( error ) goto done ; gsel = GSEL ( GUEST_CODE_SEL , SEL_KPL ) ; if ( ( error = vm_set_register ( vmctx , vcpu , VM_REG_GUEST_CS , gsel ) ) != 0 ) goto done ; gsel = GSEL ( GUEST_DATA_SEL , SEL_KPL ) ; if ( ( error = vm_set_register ( vmctx , vcpu , VM_REG_GUEST_DS , gsel ) ) != 0 ) goto done ; if ( ( error = vm_set_register ( vmctx , vcpu , VM_REG_GUEST_ES , gsel ) ) != 0 ) goto done ; if ( ( error = vm_set_register ( vmctx , vcpu , VM_REG_GUEST_FS , gsel ) ) != 0 ) goto done ; if ( ( error = vm_set_register ( vmctx , vcpu , VM_REG_GUEST_GS , gsel ) ) != 0 ) goto done ; if ( ( error = vm_set_register ( vmctx , vcpu , VM_REG_GUEST_SS , gsel ) ) != 0 ) goto done ; gsel = GSEL ( GUEST_TSS_SEL , SEL_KPL ) ; if ( ( error = vm_set_register ( vmctx , vcpu , VM_REG_GUEST_TR , gsel ) ) != 0 ) goto done ; if ( ( error = vm_set_register ( vmctx , vcpu , VM_REG_GUEST_LDTR , 0 ) ) != 0 ) goto done ; if ( ( error = vm_set_register ( vmctx , vcpu , VM_REG_GUEST_RIP , eip ) ) != 0 ) goto done ; if ( ( error = vm_set_register ( vmctx , vcpu , VM_REG_GUEST_RSP , esp ) ) != 0 ) goto done ; error = 0 ; done : return ( error ) ; }
Setup the 'vcpu' register set such that it will begin execution at
 'eip' in flat mode.
Setup the ' vcpu ' register set such that it will begin execution at ' eip ' in flat mode .
/* A 32-bit guest requires unrestricted mode. */ /*
	 * Forcing EFER to 0 causes bhyve to clear the "IA-32e guest
	 * mode" entry control.
	 */ /* Place the TSS one page above the GDT. */ /* LDTR is pointing to the null selector */ /* entry point */