Skip to content
Snippets Groups Projects
Commit 9b15b8cd authored by iliya.saroukha's avatar iliya.saroukha :first_quarter_moon:
Browse files

feat: using vmxon and vmxoff inline assembly snippets from the linux kernel source code

Everything seems to be executing correctly now, even after repeated
insmod/rmmod
parent d9abf4ad
Branches
No related tags found
No related merge requests found
...@@ -33,9 +33,10 @@ static int cr4_enable_vmx(void) { ...@@ -33,9 +33,10 @@ static int cr4_enable_vmx(void) {
unsigned long cr4; unsigned long cr4;
/*BUG: Need to somehow switch to a CPU whose VMXE bit hasn't be modified*/ /*BUG: Need to somehow switch to a CPU whose VMXE bit hasn't be modified*/
if ((__read_cr4() >> 13) & 1) { /*NOTE: seems like this bit is always set on every processor, weird..*/
return -EBUSY; /*if ((__read_cr4() >> 13) & 1) {*/
} /* return -EBUSY;*/
/*}*/
__asm__ volatile("mov %%cr4, %0" : "=r"(cr4)); __asm__ volatile("mov %%cr4, %0" : "=r"(cr4));
cr4 |= (1UL << 13); cr4 |= (1UL << 13);
...@@ -82,7 +83,7 @@ static unsigned char vmxon(unsigned long long pa) { ...@@ -82,7 +83,7 @@ static unsigned char vmxon(unsigned long long pa) {
/*asm goto("1: vmxon %[vmxon_pointer]\n\t" _ASM_EXTABLE(1b, % l[fault])*/ /*asm goto("1: vmxon %[vmxon_pointer]\n\t" _ASM_EXTABLE(1b, % l[fault])*/
/* :*/ /* :*/
/* : [vmxon_pointer] "m"(vmxon_pointer)*/ /* : [vmxon_pointer] "m"(pa)*/
/* :*/ /* :*/
/* : fault);*/ /* : fault);*/
...@@ -92,6 +93,65 @@ static unsigned char vmxon(unsigned long long pa) { ...@@ -92,6 +93,65 @@ static unsigned char vmxon(unsigned long long pa) {
DEBUG_FMT("RFLAGS: 0x%llx\n", rflags); DEBUG_FMT("RFLAGS: 0x%llx\n", rflags);
return ret; return ret;
/* unsigned long long msr;*/
/**/
/* cr4_set_bits(X86_CR4_VMXE);*/
/**/
/* __asm__ goto("1: vmxon %[vmxon_pointer]\n\t" _ASM_EXTABLE(1b,
* %l[fault])*/
/* :*/
/* : [vmxon_pointer] "m"(vmxon_pointer)*/
/* :*/
/* : fault);*/
/* return 0;*/
/**/
/*fault:*/
/* WARN_ONCE(1, "VMXON faulted, MSR_IA32_FEAT_CTL (0x3a) = 0x%llx\n",*/
/* rdmsrl_safe(MSR_IA32_FEAT_CTL, &msr) ? 0xdeadbeef : msr);*/
/* cr4_clear_bits(X86_CR4_VMXE);*/
/**/
/* return -EFAULT;*/
}
/*NOTE: arch/x86/kvm/vmx/vmx.c:2824 v6.12.10*/
static int kvm_cpu_vmxon(unsigned long long vmxon_pointer) {
unsigned long long msr;
cr4_set_bits(X86_CR4_VMXE);
// clang-format off
asm goto("1: vmxon %[vmxon_pointer]\n\t" _ASM_EXTABLE(1b, %l[fault])
:
: [vmxon_pointer] "m"(vmxon_pointer)
:
: fault);
// clang-format on
return 0;
fault:
WARN_ONCE(1, "VMXON faulted, MSR_IA32_FEAT_CTL (0x3a) = 0x%llx\n",
rdmsrl_safe(MSR_IA32_FEAT_CTL, &msr) ? 0xdeadbeef : msr);
cr4_clear_bits(X86_CR4_VMXE);
return -EFAULT;
}
/*NOTE: arch/x86/kvm/vmx/vmx.c:742 v6.12.10*/
static int kvm_cpu_vmxoff(void) {
// clang-format off
asm goto("1: vmxoff\n\t" _ASM_EXTABLE(1b, %l[fault])::
: "cc", "memory"
: fault);
// clang-format on
cr4_clear_bits(X86_CR4_VMXE);
return 0;
fault:
cr4_clear_bits(X86_CR4_VMXE);
return -EIO;
} }
static int my_init(void) { static int my_init(void) {
...@@ -154,13 +214,14 @@ static int my_init(void) { ...@@ -154,13 +214,14 @@ static int my_init(void) {
unsigned char vmxon_ret = 0; unsigned char vmxon_ret = 0;
if ((vmxon_ret = vmxon(vmxon_region.pa) != 0)) { /*if ((vmxon_ret = vmxon(vmxon_region.pa) != 0)) {*/
if ((vmxon_ret = kvm_cpu_vmxon(vmxon_region.pa) != 0)) {
/*unsigned long vm_err = __rdmsr(0x4400);*/ /*unsigned long vm_err = __rdmsr(0x4400);*/
/*pr_err("VM_ERR val = 0x%lx\n", vm_err);*/ /*pr_err("VM_ERR val = 0x%lx\n", vm_err);*/
cr4_clear_bits(13); cr4_clear_bits(13);
kfree(vmxon_region.va); kfree(vmxon_region.va);
__asm__ volatile("vmxoff"); /*__asm__ volatile("vmxoff");*/
pr_err("`vmxon` failed with return code %d\n", vmxon_ret); pr_err("`vmxon` failed with return code %d\n", vmxon_ret);
return -1; return -1;
} }
...@@ -172,7 +233,13 @@ static int my_init(void) { ...@@ -172,7 +233,13 @@ static int my_init(void) {
static void my_exit(void) { static void my_exit(void) {
pr_info("Executing VMXOFF\n"); pr_info("Executing VMXOFF\n");
__asm__ volatile("vmxoff"); /*__asm__ volatile("vmxoff");*/
int vmxoff;
if ((vmxoff = kvm_cpu_vmxoff()) != 0) {
pr_err("Failed to execute VMXOFF\n");
return;
}
pr_info("Freeing memory of the VMXON region\n"); pr_info("Freeing memory of the VMXON region\n");
kfree(vmxon_region.va); kfree(vmxon_region.va);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment