Skip to content
This repository was archived by the owner on Jan 28, 2023. It is now read-only.

Commit 4eca5b6

Browse files
committed
Ported platform-specific assembly sources to NASM
1 parent 6f693d4 commit 4eca5b6

28 files changed

Lines changed: 942 additions & 3252 deletions

File tree

core/cpu.c

Lines changed: 56 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ static cpuid_cache_t cache = {
4343
.initialized = 0
4444
};
4545

46-
static vmx_error_t cpu_vmentry_failed(struct vcpu_t *vcpu, vmx_error_t err);
46+
static void cpu_vmentry_failed(struct vcpu_t *vcpu, vmx_result_t result);
4747
static int cpu_vmexit_handler(struct vcpu_t *vcpu, exit_reason_t exit_reason,
4848
struct hax_tunnel *htun);
4949

@@ -227,10 +227,10 @@ static void vmread_cr(struct vcpu_t *vcpu)
227227
state->_cr4 = (cr4 & ~cr4_mask) | (state->_cr4 & cr4_mask);
228228
}
229229

230-
vmx_error_t cpu_vmx_vmptrld(struct per_cpu_data *cpu_data, paddr_t vmcs,
231-
struct vcpu_t *vcpu)
230+
vmx_result_t cpu_vmx_vmptrld(struct per_cpu_data *cpu_data, paddr_t vmcs,
231+
struct vcpu_t *vcpu)
232232
{
233-
vmx_error_t r = __vmptrld(vmcs);
233+
vmx_result_t r = asm_vmptrld(&vmcs);
234234
return r;
235235
}
236236

@@ -324,9 +324,9 @@ static int cpu_vmexit_handler(struct vcpu_t *vcpu, exit_reason_t exit_reason,
324324
#ifdef CONFIG_DARWIN
325325
__attribute__ ((__noinline__))
326326
#endif
327-
vmx_error_t cpu_vmx_run(struct vcpu_t *vcpu, struct hax_tunnel *htun)
327+
vmx_result_t cpu_vmx_run(struct vcpu_t *vcpu, struct hax_tunnel *htun)
328328
{
329-
uint64 rflags = 0;
329+
vmx_result_t result = 0;
330330
mword host_rip;
331331

332332
/* prepare the RIP */
@@ -338,7 +338,7 @@ vmx_error_t cpu_vmx_run(struct vcpu_t *vcpu, struct hax_tunnel *htun)
338338
* put the vmwrite before is_running, so that the vcpu->cpu_id is set
339339
* when we check vcpu->is_running in vcpu_pause
340340
*/
341-
host_rip = get_rip();
341+
host_rip = vmx_get_rip();
342342
vmwrite(vcpu, HOST_RIP, (mword)host_rip);
343343
vcpu->is_running = 1;
344344
#ifdef DEBUG_HOST_STATE
@@ -349,7 +349,7 @@ vmx_error_t cpu_vmx_run(struct vcpu_t *vcpu, struct hax_tunnel *htun)
349349

350350
load_guest_msr(vcpu);
351351

352-
rflags = __vmx_run(vcpu->state, vcpu->launched);
352+
result = asm_vmxrun(vcpu->state, vcpu->launched);
353353

354354
vcpu->is_running = 0;
355355
save_guest_msr(vcpu);
@@ -360,13 +360,12 @@ vmx_error_t cpu_vmx_run(struct vcpu_t *vcpu, struct hax_tunnel *htun)
360360
compare_host_state(vcpu);
361361
#endif
362362

363-
hax_debug("\ncpu_vmx_run %llx, FAIL %llx\n", rflags, rflags & VMX_FAIL_MASK);
364-
if (rflags & VMX_FAIL_MASK) {
365-
cpu_vmentry_failed(vcpu, rflags & VMX_FAIL_MASK);
363+
if (result != VMX_SUCCEED) {
364+
cpu_vmentry_failed(vcpu, result);
366365
htun->_exit_reason = 0;
367366
htun->_exit_status = HAX_EXIT_UNKNOWN;
368367
}
369-
return (rflags & VMX_FAIL_MASK);
368+
return result;
370369
}
371370

372371
void vcpu_handle_vmcs_pending(struct vcpu_t *vcpu)
@@ -402,7 +401,7 @@ void vcpu_handle_vmcs_pending(struct vcpu_t *vcpu)
402401
/* Return the value same as ioctl value */
403402
int cpu_vmx_execute(struct vcpu_t *vcpu, struct hax_tunnel *htun)
404403
{
405-
vmx_error_t err = 0;
404+
vmx_result_t res = 0;
406405
int ret;
407406
preempt_flag flags;
408407
struct vcpu_state_t *state = vcpu->state;
@@ -449,9 +448,9 @@ int cpu_vmx_execute(struct vcpu_t *vcpu, struct hax_tunnel *htun)
449448
vmwrite(vcpu, GUEST_TR_AR, temp);
450449
}
451450

452-
err = cpu_vmx_run(vcpu, htun);
453-
if (err) {
454-
hax_debug("cpu_vmx_run error, code:%lx\n", err);
451+
res = cpu_vmx_run(vcpu, htun);
452+
if (res) {
453+
hax_debug("cpu_vmx_run error, code:%xlx\n", res);
455454
if ((vmcs_err = put_vmcs(vcpu, &flags))) {
456455
hax_panic_vcpu(vcpu, "put_vmcs fail: %x\n", vmcs_err);
457456
hax_panic_log(vcpu);
@@ -520,29 +519,29 @@ void restore_host_cr4_vmxe(struct per_cpu_data *cpu_data);
520519

521520
uint32 log_host_cr4_vmxe = 0;
522521
uint64 log_host_cr4 = 0;
523-
vmx_error_t log_vmxon_err = 0;
522+
vmx_result_t log_vmxon_res = 0;
524523
uint64 log_vmxon_addr = 0;
525524
uint32 log_vmxon_err_type1 = 0;
526525
uint32 log_vmxon_err_type2 = 0;
527526
uint32 log_vmxon_err_type3 = 0;
528527
uint32 log_vmclear_err = 0;
529528
uint32 log_vmptrld_err = 0;
530529
uint32 log_vmxoff_no = 0;
531-
vmx_error_t log_vmxoff_err = 0;
530+
vmx_result_t log_vmxoff_res = 0;
532531

533532
void hax_clear_panic_log(struct vcpu_t *vcpu)
534533
{
535534
log_host_cr4_vmxe = 0;
536535
log_host_cr4 = 0;
537-
log_vmxon_err = 0;
536+
log_vmxon_res = 0;
538537
log_vmxon_addr = 0;
539538
log_vmxon_err_type1 = 0;
540539
log_vmxon_err_type2 = 0;
541540
log_vmxon_err_type3 = 0;
542541
log_vmclear_err = 0;
543542
log_vmptrld_err = 0;
544543
log_vmxoff_no = 0;
545-
log_vmxoff_err = 0;
544+
log_vmxoff_res = 0;
546545
}
547546

548547
void hax_panic_log(struct vcpu_t *vcpu)
@@ -551,15 +550,15 @@ void hax_panic_log(struct vcpu_t *vcpu)
551550
return;
552551
hax_error("log_host_cr4_vmxe: %x\n", log_host_cr4_vmxe);
553552
hax_error("log_host_cr4 %llx\n", log_host_cr4);
554-
hax_error("log_vmxon_err %lx\n", log_vmxon_err);
553+
hax_error("log_vmxon_res %x\n", log_vmxon_res);
555554
hax_error("log_vmxon_addr %llx\n", log_vmxon_addr);
556555
hax_error("log_vmxon_err_type1 %x\n", log_vmxon_err_type1);
557556
hax_error("log_vmxon_err_type2 %x\n", log_vmxon_err_type2);
558557
hax_error("log_vmxon_err_type3 %x\n", log_vmxon_err_type3);
559558
hax_error("log_vmclear_err %x\n", log_vmclear_err);
560559
hax_error("log_vmptrld_err %x\n", log_vmptrld_err);
561560
hax_error("log_vmoff_no %x\n", log_vmxoff_no);
562-
hax_error("log_vmoff_err %lx\n", log_vmxoff_err);
561+
hax_error("log_vmxoff_res %x\n", log_vmxoff_res);
563562
}
564563

565564
uint32 load_vmcs(struct vcpu_t *vcpu, preempt_flag *flags)
@@ -597,7 +596,7 @@ uint32 load_vmcs(struct vcpu_t *vcpu, preempt_flag *flags)
597596
vmcs_phy = hax_page_pa(cpu_data->vmcs_page);
598597

599598

600-
if (__vmptrld(vmcs_phy) != VMX_SUCCEED) {
599+
if (asm_vmptrld(&vmcs_phy) != VMX_SUCCEED) {
601600
hax_error("HAX: vmptrld failed (%08llx)\n", vmcs_phy);
602601
cpu_vmxroot_leave();
603602
log_vmxon_err_type3 = 1;
@@ -631,10 +630,9 @@ void restore_host_cr4_vmxe(struct per_cpu_data *cpu_data)
631630

632631
uint32 put_vmcs(struct vcpu_t *vcpu, preempt_flag *flags)
633632
{
634-
int cpu_id = hax_cpuid();
635-
struct per_cpu_data *cpu_data = hax_cpu_data[cpu_id];
633+
struct per_cpu_data *cpu_data = current_cpu_data();
636634
paddr_t vmcs_phy;
637-
vmx_error_t vmxoff_err = 0;
635+
vmx_result_t vmxoff_res = 0;
638636
if (vcpu && cpu_data->nested > 0) {
639637
cpu_data->nested--;
640638
goto out;
@@ -645,20 +643,20 @@ uint32 put_vmcs(struct vcpu_t *vcpu, preempt_flag *flags)
645643
else
646644
vmcs_phy = hax_page_pa(cpu_data->vmcs_page);
647645

648-
if (__vmclear(vmcs_phy) != VMX_SUCCEED) {
649-
hax_error("HAX: vmclear ailed (%llx)\n", vmcs_phy);
646+
if (asm_vmclear(&vmcs_phy) != VMX_SUCCEED) {
647+
hax_error("HAX: vmclear failed (%llx)\n", vmcs_phy);
650648
log_vmclear_err = 1;
651649
}
652650

653651
cpu_data->current_vcpu = NULL;
654652

655-
vmxoff_err = cpu_vmxroot_leave();
653+
vmxoff_res = cpu_vmxroot_leave();
656654
cpu_data->other_vmcs = VMCS_NONE;
657655
if (vcpu && vcpu->is_vmcs_loaded)
658656
vcpu->is_vmcs_loaded = 0;
659657
out:
660658
hax_enable_preemption(flags);
661-
return vmxoff_err;
659+
return vmxoff_res;
662660
}
663661

664662
void load_vmcs_common(struct vcpu_t *vcpu)
@@ -695,14 +693,14 @@ void load_vmcs_common(struct vcpu_t *vcpu)
695693
}
696694

697695

698-
static vmx_error_t cpu_vmentry_failed(struct vcpu_t *vcpu, vmx_error_t err)
696+
static void cpu_vmentry_failed(struct vcpu_t *vcpu, vmx_result_t result)
699697
{
700-
hax_debug("HAX: VM entry failed: err=%lx RIP=%08lx\n",
701-
err, (mword)vmread(vcpu, GUEST_RIP));
698+
hax_debug("HAX: VM entry failed: result=%x RIP=%08lx\n",
699+
result, (mword)vmread(vcpu, GUEST_RIP));
702700

703701
//dump_vmcs();
704702

705-
if (err == VMX_FAIL_VALID) {
703+
if (result == VMX_FAIL_VALID) {
706704
hax_log("HAX: Prev exit: %llx error code: %llx\n",
707705
vmread(vcpu, VM_EXIT_INFO_REASON),
708706
vmread(vcpu, VMX_INSTRUCTION_ERROR_CODE));
@@ -713,17 +711,16 @@ static vmx_error_t cpu_vmentry_failed(struct vcpu_t *vcpu, vmx_error_t err)
713711

714712
hax_log("HAX: VM entry failed\n");
715713
hax_log("end of cpu_vmentry_failed\n");
716-
return err;
717714
}
718715

719-
vmx_error_t cpu_vmxroot_leave(void)
716+
vmx_result_t cpu_vmxroot_leave(void)
720717
{
721718
struct per_cpu_data *cpu_data = current_cpu_data();
722-
vmx_error_t err = VMX_SUCCEED;
719+
vmx_result_t result = VMX_SUCCEED;
723720

724721
if (cpu_data->vmm_flag & VMXON_HAX) {
725-
err = __vmxoff();
726-
if (!(err & VMX_FAIL_MASK)) {
722+
result = asm_vmxoff();
723+
if (result == VMX_SUCCEED) {
727724
cpu_data->vmm_flag &= ~VMXON_HAX;
728725
restore_host_cr4_vmxe(cpu_data);
729726
} else {
@@ -736,20 +733,21 @@ vmx_error_t cpu_vmxroot_leave(void)
736733
" Hypervisor Framework) is running\n");
737734
#else
738735
// It should not go here in Win64/win32
739-
err = VMX_FAIL_VALID;
736+
result = VMX_FAIL_VALID;
740737
hax_error("NO VMXOFF.......\n");
741738
#endif
742739
}
743-
cpu_data->vmxoff_err = err;
740+
cpu_data->vmxoff_res = result;
744741

745-
return err;
742+
return result;
746743
}
747744

748-
vmx_error_t cpu_vmxroot_enter(void)
745+
vmx_result_t cpu_vmxroot_enter(void)
749746
{
750747
struct per_cpu_data *cpu_data = current_cpu_data();
751748
uint64 fc_msr;
752-
vmx_error_t err = VMX_SUCCEED;
749+
paddr_t vmxon_addr;
750+
vmx_result_t result = VMX_SUCCEED;
753751

754752
cpu_data->host_cr4_vmxe = (get_cr4() & CR4_VMXE);
755753
if (cpu_data->host_cr4_vmxe) {
@@ -782,18 +780,19 @@ vmx_error_t cpu_vmxroot_enter(void)
782780
ia32_wrmsr(IA32_FEATURE_CONTROL,
783781
fc_msr | FC_LOCKED | FC_VMXON_OUTSMX);
784782

785-
err = __vmxon(hax_page_pa(cpu_data->vmxon_page));
783+
vmxon_addr = hax_page_pa(cpu_data->vmxon_page);
784+
result = asm_vmxon(&vmxon_addr);
786785

787-
log_vmxon_err = err;
788-
log_vmxon_addr = hax_page_pa(cpu_data->vmxon_page);
786+
log_vmxon_res = result;
787+
log_vmxon_addr = vmxon_addr;
789788

790-
if (!(err & VMX_FAIL_MASK)) {
789+
if (result == VMX_SUCCEED) {
791790
cpu_data->vmm_flag |= VMXON_HAX;
792791
} else {
793792
bool fatal = true;
794793

795794
#ifdef __MACH__
796-
if ((err & VMX_FAIL_INVALID) && cpu_data->host_cr4_vmxe) {
795+
if ((result == VMX_FAIL_INVALID) && cpu_data->host_cr4_vmxe) {
797796
// On macOS, if VMXON fails with VMX_FAIL_INVALID and host CR4.VMXE
798797
// was already set, it is very likely that another VMM (VirtualBox
799798
// or any VMM based on macOS Hypervisor Framework, e.g. Docker) is
@@ -804,22 +803,23 @@ vmx_error_t cpu_vmxroot_enter(void)
804803
// is not actually in VMX operation, VMPTRST will probably cause a
805804
// host reboot. But we don't have a better choice, and it is worth
806805
// taking the risk.
807-
__vmptrst();
806+
paddr_t vmcs_addr;
807+
asm_vmptrst(&vmcs_addr);
808808

809809
// It is still alive - Just assumption is right.
810810
fatal = false;
811-
err = VMX_SUCCEED;
811+
result = VMX_SUCCEED;
812812
// Indicate that it is not necessary to call VMXOFF later
813813
cpu_data->vmm_flag &= ~VMXON_HAX;
814814
}
815815
#endif
816816

817817
if (fatal) {
818-
hax_error("VMXON failed for region 0x%llx (err=0x%x, vmxe=%x)\n",
819-
hax_page_pa(cpu_data->vmxon_page), (uint32)err,
818+
hax_error("VMXON failed for region 0x%llx (result=0x%x, vmxe=%x)\n",
819+
hax_page_pa(cpu_data->vmxon_page), (uint32)result,
820820
(uint32)cpu_data->host_cr4_vmxe);
821821
restore_host_cr4_vmxe(cpu_data);
822-
if (err & VMX_FAIL_INVALID) {
822+
if (result == VMX_FAIL_INVALID) {
823823
log_vmxon_err_type1 = 1;
824824
} else {
825825
// TODO: Should VMX_FAIL_VALID be ignored? The current VMCS can
@@ -828,6 +828,6 @@ vmx_error_t cpu_vmxroot_enter(void)
828828
}
829829
}
830830
}
831-
cpu_data->vmxon_err = err;
832-
return err;
831+
cpu_data->vmxon_res = result;
832+
return result;
833833
}

core/cpuid.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,14 @@ typedef union cpuid_feature_t {
4848
void cpuid_query_leaf(cpuid_args_t *args, uint32_t leaf)
4949
{
5050
args->eax = leaf;
51-
__handle_cpuid(args);
51+
asm_cpuid(args);
5252
}
5353

5454
void cpuid_query_subleaf(cpuid_args_t *args, uint32_t leaf, uint32_t subleaf)
5555
{
5656
args->eax = leaf;
5757
args->ecx = subleaf;
58-
__handle_cpuid(args);
58+
asm_cpuid(args);
5959
}
6060

6161
void cpuid_host_init(cpuid_cache_t *cache)

core/ept.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -330,12 +330,12 @@ static void invept_smpfunc(struct invept_bundle *bundle)
330330

331331
smp_mb();
332332
cpu_data = current_cpu_data();
333-
cpu_data->invept_err = VMX_SUCCEED;
333+
cpu_data->invept_res = VMX_SUCCEED;
334334

335335
cpu_vmxroot_enter();
336336

337-
if (!(cpu_data->vmxon_err & VMX_FAIL_MASK)) {
338-
cpu_data->invept_err = __invept(bundle->type, bundle->desc);
337+
if (cpu_data->vmxon_res == VMX_SUCCEED) {
338+
cpu_data->invept_res = asm_invept(bundle->type, bundle->desc);
339339
cpu_vmxroot_leave();
340340
}
341341
}
@@ -346,7 +346,7 @@ void invept(hax_vm_t *hax_vm, uint type)
346346
struct invept_desc desc = { eptp_value, 0 };
347347
struct invept_bundle bundle;
348348
int cpu_id;
349-
uint32 err;
349+
uint32 res;
350350

351351
if (!ept_has_cap(ept_cap_invept)) {
352352
hax_warning("INVEPT was not called due to missing host support"
@@ -394,20 +394,20 @@ void invept(hax_vm_t *hax_vm, uint type)
394394
continue;
395395
}
396396

397-
err = (uint32)cpu_data->vmxon_err;
398-
if (err & VMX_FAIL_MASK) {
397+
res = (uint32)cpu_data->vmxon_res;
398+
if (res != VMX_SUCCEED) {
399399
hax_error("[Processor #%d] INVEPT was not called, because VMXON"
400-
" failed (err=0x%x)\n", cpu_id, err);
400+
" failed (err=0x%x)\n", cpu_id, res);
401401
} else {
402-
err = (uint32)cpu_data->invept_err;
403-
if (err & VMX_FAIL_MASK) {
402+
res = (uint32)cpu_data->invept_res;
403+
if (res != VMX_SUCCEED) {
404404
hax_error("[Processor #%d] INVEPT failed (err=0x%x)\n", cpu_id,
405-
err);
405+
res);
406406
}
407-
err = (uint32)cpu_data->vmxoff_err;
408-
if (err & VMX_FAIL_MASK) {
407+
res = (uint32)cpu_data->vmxoff_res;
408+
if (res != VMX_SUCCEED) {
409409
hax_error("[Processor #%d] INVEPT was called, but VMXOFF failed"
410-
" (err=0x%x)\n", cpu_id, err);
410+
" (err=0x%x)\n", cpu_id, res);
411411
}
412412
}
413413
}

0 commit comments

Comments
 (0)