Commit c4fc774c authored by Charles Jacobsen's avatar Charles Jacobsen Committed by Vikram Narayanan

Simple blob successfully runs and returns in vmx.

In the process of debugging, major corrections and
debug checks implemented (this is a big squash):
-- coded up entry checks documented in Intel SDM
   V3 chp 26 (this should help later if settings
   are changed, make it less risky to experiment
   and give more confidence)
-- fixed host tr base addr bug (the worst bug! caused
   system to hang and then crash, since the tss
   was erroneous...)
-- fixed vmx_entry to properly set host rsp before
   entry
-- setting host sysenter and idt info
-- fixed cs ar bytes bug
-- fixed gdt limit bug
-- fixed tr type bug
-- extra settings added to cr0 and cr4, but may
   not be needed ... (debug fix attempt)
-- lstar mstar autoload, may not be needed ...
   (debug fix attempt)
parent 37b45a8f
......@@ -111,7 +111,7 @@ struct lcd_arch_vmcs {
char data[0];
};
#define LCD_ARCH_NUM_AUTOLOAD_MSRS 0
#define LCD_ARCH_NUM_AUTOLOAD_MSRS 1
enum lcd_arch_reg {
LCD_ARCH_REGS_RAX = 0,
......@@ -226,6 +226,11 @@ void lcd_arch_exit(void);
* the settings and most register values.
*/
struct lcd_arch *lcd_arch_create(void);
/**
* Does logical consistency checks (e.g., runs through checks
* listed in Intel SDM V3 26.1, 26.2, and 26.3).
*/
int lcd_arch_check(struct lcd_arch *vcpu);
/**
* Tears down arch-dep part of LCD. (If LCD is launched on
* some cpu, it will become inactive.)
......@@ -348,7 +353,7 @@ int lcd_arch_set_gva_root(struct lcd_arch *vcpu, gpa_t a);
#define LCD_ARCH_GS_BASE __gpa(0UL)
#define LCD_ARCH_GS_LIMIT 0xFFFFFFFF
#define LCD_ARCH_GDTR_BASE __gpa(1UL << PAGE_SHIFT)
#define LCD_ARCH_GDTR_LIMIT ((u32)~(PAGE_SIZE - 1))
#define LCD_ARCH_GDTR_LIMIT 0xFFFUL
#define LCD_ARCH_TSS_BASE __gpa(2UL << PAGE_SHIFT)
/* tss base + limit = address of last byte in tss, hence -1 */
#define LCD_ARCH_TSS_LIMIT (sizeof(struct lcd_arch_tss) - 1)
......
......@@ -2,6 +2,6 @@
# Makefile for VMX code for LCDs
#
ccflags-y += -Werror
ccflags-y += -Werror -O0
obj-$(CONFIG_LCD_INTEL) += lcd-domains-arch.o
......@@ -186,7 +186,7 @@ fail3:
fail2:
kfree(lcd);
fail1:
return -1;
return ret;
}
......@@ -316,14 +316,116 @@ fail_alloc:
static int test08(void)
{
struct lcd_arch *lcd;
hva_t pgd;
int ret;
lcd = lcd_arch_create();
if (!lcd) {
printk(KERN_ERR "lcd arch : test08 failed to create lcd\n");
return -1;
ret = 1;
goto fail1;
}
pgd = __hva(__get_free_page(GFP_KERNEL));
if (!hva_val(pgd)) {
printk(KERN_ERR "lcd arch: test08 failed to alloc page\n");
ret = 1;
goto fail2;
}
ret = lcd_arch_ept_map(lcd, __gpa(0), hva2hpa(pgd), 1, 0);
if (ret) {
printk(KERN_ERR "lcd arch: test08 error mapping pgd\n");
goto fail3;
}
ret = lcd_arch_set_gva_root(lcd, __gpa(0));
if (ret) {
printk(KERN_ERR "lcd arch: test08 error setting gva root\n");
goto fail4;
}
ret = lcd_arch_set_pc(lcd, __gpa(0));
if (ret) {
printk(KERN_ERR "lcd arch: test08 error setting pc\n");
goto fail5;
}
if (lcd_arch_check(lcd)) {
printk(KERN_ERR "lcd arch: test08 failed a check\n");
ret = -1;
goto fail6;
}
ret = 0;
goto done;
done:
fail6:
fail5:
fail4:
lcd_arch_ept_unmap(lcd, __gpa(0));
fail3:
free_page(hva_val(pgd));
fail2:
lcd_arch_destroy(lcd);
fail1:
return ret;
}
static int test09(void)
{
if (!vmx_addr_is_canonical(0UL)) {
printk(KERN_ERR "lcd arch: test09.1 failed\n");
return -1;
}
if (vmx_addr_is_canonical(1UL << 63)) {
printk(KERN_ERR "lcd arch: test09.2 failed\n");
return -1;
}
if (vmx_addr_is_canonical(0xFFFFUL << 48)) {
printk(KERN_ERR "lcd arch: test09.3 failed\n");
return -1;
}
if (!vmx_addr_is_canonical(0xFFFF8UL << 44)) {
printk(KERN_ERR "lcd arch: test09.4 failed\n");
return -1;
}
if (!vmx_addr_is_canonical(0x00007UL << 44)) {
printk(KERN_ERR "lcd arch: test09.5 failed\n");
return -1;
}
return 0;
}
static int test10(void)
{
u32 width;
width = cpuid_eax(0x80000008) & 0xff;
if (vmx_bad_phys_addr(0xff)) {
printk(KERN_ERR "lcd vmx: test10.0 failed\n");
return -1;
}
if (vmx_bad_phys_addr(1UL << (width - 1))) {
printk(KERN_ERR "lcd vmx: test10.1 failed\n");
return -1;
}
if (!vmx_bad_phys_addr(1UL << width)) {
printk(KERN_ERR "lcd vmx: test10.2 failed\n");
return -1;
}
if (!vmx_bad_phys_addr(-1ULL)) {
printk(KERN_ERR "lcd vmx: test10.3 failed\n");
return -1;
}
if (width >= 40 && vmx_bad_phys_addr(0x30682f000)) {
printk(KERN_ERR "lcd vmx: test10.4 failed\n");
return -1;
}
return 0;
}
......@@ -345,5 +447,10 @@ static void lcd_arch_tests(void)
return;
if (test08())
return;
if (test09())
return;
if (test10())
return;
printk(KERN_ERR "lcd vmx: all tests passed!\n");
return;
}
This diff is collapsed.
......@@ -892,7 +892,7 @@ static int lcd_do_run_blob_once(struct lcd *lcd)
* Continue
*/
printk(KERN_ERR "lcd_run_blob: got external intr\n");
r = 0;
r = -EIO;
goto out;
case LCD_ARCH_STATUS_EPT_FAULT:
/*
......@@ -924,7 +924,7 @@ static int lcd_do_run_blob_once(struct lcd *lcd)
goto out;
} else {
printk(KERN_ERR "lcd_run_blob: lcd yielded, exiting lcd...\n");
r = 0;
r = -EIO;
goto out;
}
}
......@@ -936,6 +936,7 @@ out:
static int lcd_do_run_blob(struct lcd *lcd)
{
int r;
while (1) {
r = lcd_do_run_blob_once(lcd);
if (r)
......@@ -1035,8 +1036,16 @@ static int lcd_init_blob(struct lcd *lcd, unsigned char *blob,
goto fail4;
}
return 0;
r = lcd_do_run_blob(lcd);
if (r) {
printk(KERN_ERR "lcd_init_blob: error running blob: err %d\n",
r);
goto fail4;
}
r = 0;
goto done;
done:
fail4:
lcd_mm_gva_unmap_range(lcd, __gva(0), npages);
fail3:
......@@ -1103,12 +1112,9 @@ static int lcd_run_blob(struct lcd_blob_info *bi)
goto fail5;
}
/*
* Run blob until it yields or fails
*/
r = lcd_do_run_blob(lcd);
goto done;
r = 0;
goto done;
done:
fail5:
lcd_destroy(lcd);
......
......@@ -585,5 +585,6 @@ static void lcd_tests(void)
return;
if (test09())
return;
printk(KERN_ERR "lcd-domains: all tests passed!\n");
return;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment