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

fix: returning either EFAULT or EBUSY depending on the context, lots still to investigate...

parent 4755f51d
No related branches found
No related tags found
No related merge requests found
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include <asm/page.h> #include <asm/page.h>
#include <asm/page_types.h> #include <asm/page_types.h>
#include <asm/paravirt.h> #include <asm/paravirt.h>
#include <linux/errno.h>
#include <linux/gfp_types.h> #include <linux/gfp_types.h>
#include <linux/init.h> /* Needed for the macros */ #include <linux/init.h> /* Needed for the macros */
#include <linux/kern_levels.h> #include <linux/kern_levels.h>
...@@ -11,7 +12,9 @@ ...@@ -11,7 +12,9 @@
#include <linux/slab.h> #include <linux/slab.h>
/*============== my includes ==============*/ /*============== my includes ==============*/
#include "asm/smp.h"
#include "asm/special_insns.h" #include "asm/special_insns.h"
#include "asm/tlbflush.h"
#include "debug/debug.h" #include "debug/debug.h"
#include "msr/msr.h" #include "msr/msr.h"
#include "region/vxmon_reg.h" #include "region/vxmon_reg.h"
...@@ -26,15 +29,22 @@ ...@@ -26,15 +29,22 @@
static struct vmxon_region_t vmxon_region; static struct vmxon_region_t vmxon_region;
static void cr4_enable_vmx(void) { 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*/
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);
__asm__ volatile("mov %0, %%cr4" ::"r"(cr4)); __asm__ volatile("mov %0, %%cr4" ::"r"(cr4));
DEBUG_FMT("CR4[13].VMXE set? %s\n", DEBUG_FMT("CR4[13].VMXE set? %s\n",
(__read_cr4() >> 13) & 1 ? "true" : "false"); (__read_cr4() >> 13) & 1 ? "true" : "false");
return 0;
} }
static bool vmx_support_cpuid(void) { static bool vmx_support_cpuid(void) {
...@@ -102,15 +112,16 @@ static int my_init(void) { ...@@ -102,15 +112,16 @@ static int my_init(void) {
pr_info("Checking VMX support using CPUID\n"); pr_info("Checking VMX support using CPUID\n");
if (!vmx_support_cpuid()) { if (!vmx_support_cpuid()) {
pr_err("VMX isn't supported\n"); pr_err("VMX isn't supported\n");
return -1; return -EPERM;
} }
DEBUG_FMT("IA32_VMX_BASIC_MSR = 0x%llx\n", __rdmsr(IA32_VMX_BASIC)); DEBUG_FMT("IA32_VMX_BASIC_MSR = 0x%llx\n", __rdmsr(IA32_VMX_BASIC));
pr_info("Initializing VMXON region\n"); pr_info("Initializing VMXON region\n");
if (init_vmxon_reg(&vmxon_region) != 0) { int ret_init_vmxon;
if ((ret_init_vmxon = init_vmxon_reg(&vmxon_region)) != 0) {
pr_err("Failed to initialized the VMXON region\n"); pr_err("Failed to initialized the VMXON region\n");
return -1; return -ret_init_vmxon;
} }
pr_info("VA of the allocated region = 0x%px\n", vmxon_region.va); pr_info("VA of the allocated region = 0x%px\n", vmxon_region.va);
...@@ -124,13 +135,18 @@ static int my_init(void) { ...@@ -124,13 +135,18 @@ static int my_init(void) {
patch_control_registers(); patch_control_registers();
pr_info("Enabling VMX in CR4\n"); pr_info("Enabling VMX in CR4\n");
cr4_enable_vmx(); int ret_cr4_vmx;
if ((ret_cr4_vmx = cr4_enable_vmx()) != 0) {
pr_err("CPU not available, VMXE bit in CR4 has already been set\n");
return ret_cr4_vmx;
}
pr_info("Checking the necessary flags of the IA32_FEATURE_CONTROL_MSR\n"); pr_info("Checking the necessary flags of the IA32_FEATURE_CONTROL_MSR\n");
if (!ia32_feature_control_flags()) { if (!ia32_feature_control_flags()) {
pr_err("The flags of the IA32_FEATURE_CONTROL MSR do not permit " pr_err("The flags of the IA32_FEATURE_CONTROL MSR do not permit "
"virtualization\n"); "virtualization\n");
return -1; return -EPERM;
} }
pr_info("Executing VMXON with address = 0x%llx as its operand\n", pr_info("Executing VMXON with address = 0x%llx as its operand\n",
...@@ -141,6 +157,7 @@ static int my_init(void) { ...@@ -141,6 +157,7 @@ static int my_init(void) {
if ((vmxon_ret = vmxon(vmxon_region.pa) != 0)) { if ((vmxon_ret = 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);
kfree(vmxon_region.va); kfree(vmxon_region.va);
__asm__ volatile("vmxoff"); __asm__ volatile("vmxoff");
......
...@@ -2,25 +2,26 @@ ...@@ -2,25 +2,26 @@
#include "../msr/msr.h" #include "../msr/msr.h"
#include "vxmon_reg.h" #include "vxmon_reg.h"
#include <asm/page.h> #include <asm/page.h>
#include <linux/errno.h>
#include <linux/printk.h> #include <linux/printk.h>
#include <linux/slab.h> #include <linux/slab.h>
static int alloc_vmxon_internals(struct vmxon_region_t *reg) { static int alloc_vmxon_internals(struct vmxon_region_t *reg) {
if (!reg) { if (!reg) {
DEBUG_FMT("vmxon_reg_t isn't allocated\n"); DEBUG_FMT("vmxon_reg_t isn't allocated\n");
return -1; return -EFAULT;
} }
void *region = kzalloc(PAGE_SIZE, GFP_KERNEL); void *region = kzalloc(PAGE_SIZE, GFP_KERNEL);
if (!region) { if (!region) {
DEBUG_FMT("VMXON region allocation has failed\n"); DEBUG_FMT("VMXON region allocation has failed\n");
return -1; return -EFAULT;
} }
if (((unsigned long long)region & 0xfff) != 0) { if (((unsigned long long)region & 0xfff) != 0) {
DEBUG_FMT("Region 0x%px isn't properly aligned\n", region); DEBUG_FMT("Region 0x%px isn't properly aligned\n", region);
return -1; return -EFAULT;
} }
DEBUG_FMT( DEBUG_FMT(
...@@ -37,7 +38,7 @@ static int alloc_vmxon_internals(struct vmxon_region_t *reg) { ...@@ -37,7 +38,7 @@ static int alloc_vmxon_internals(struct vmxon_region_t *reg) {
static int write_vmcs_rev_id_to_vmxon(struct vmxon_region_t *reg) { static int write_vmcs_rev_id_to_vmxon(struct vmxon_region_t *reg) {
if (!reg) { if (!reg) {
DEBUG_FMT("vmxon_reg_t isn't allocated\n"); DEBUG_FMT("vmxon_reg_t isn't allocated\n");
return -1; return -EFAULT;
} }
DEBUG_FMT( DEBUG_FMT(
...@@ -53,13 +54,15 @@ static int write_vmcs_rev_id_to_vmxon(struct vmxon_region_t *reg) { ...@@ -53,13 +54,15 @@ static int write_vmcs_rev_id_to_vmxon(struct vmxon_region_t *reg) {
} }
int init_vmxon_reg(struct vmxon_region_t *reg) { int init_vmxon_reg(struct vmxon_region_t *reg) {
if (alloc_vmxon_internals(reg) != 0) { int ret;
return -1;
if ((ret = alloc_vmxon_internals(reg)) != 0) {
return ret;
} }
if (write_vmcs_rev_id_to_vmxon(reg) != 0) { if ((ret = write_vmcs_rev_id_to_vmxon(reg)) != 0) {
kfree(reg->va); kfree(reg->va);
return -1; return ret;
} }
return 0; return 0;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment