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

Fixed tss/stack remap bug, and double free in create.

Some data structures in struct lcd_arch are mapped in
the ept (so that the lcd has access to them). When the
ept is freed, these data structures are freed.

All tests passing now for lcd_arch_create.
parent 3360de4b
......@@ -202,9 +202,9 @@ int lcd_arch_ept_gpa_to_hpa(struct lcd_arch *vcpu, u64 gpa, u64 *hpa_out);
#define LCD_ARCH_FS_LIMIT 0xFFFFFFFF
#define LCD_ARCH_GS_BASE 0x0UL
#define LCD_ARCH_GS_LIMIT 0xFFFFFFFF
#define LCD_ARCH_GDTR_BASE 0x0000000000002000UL
#define LCD_ARCH_GDTR_BASE 0x0000000000001000UL
#define LCD_ARCH_GDTR_LIMIT ((u32)~(PAGE_SIZE - 1))
#define LCD_ARCH_TSS_BASE 0x0000000000003000UL
#define LCD_ARCH_TSS_BASE 0x0000000000002000UL
/* tss base + limit = address of last byte in tss, hence -1 */
#define LCD_ARCH_TSS_LIMIT (sizeof(struct lcd_arch_tss) - 1)
#define LCD_ARCH_IDTR_BASE 0x0UL
......
......@@ -271,31 +271,31 @@ fail_alloc:
return -1;
}
#if 0
static int test04(void)
static int test05(void)
{
struct lcd_arch *lcd;
u64 hpa;
lcd = (struct lcd_arch *)kmalloc(sizeof(*lcd), GFP_KERNEL);
if (!lcd) {
printk(KERN_ERR "lcd arch : test04 failed to alloc lcd\n");
printk(KERN_ERR "lcd arch : test05 failed to alloc lcd\n");
goto fail_alloc;
}
if (vmx_init_ept(lcd)) {
printk(KERN_ERR "lcd arch : test04 ept init failed\n");
printk(KERN_ERR "lcd arch : test05 ept init failed\n");
goto fail_ept;
}
if (vmx_init_gdt(lcd)) {
printk(KERN_ERR "lcd arch : test04 gdt init failed\n");
printk(KERN_ERR "lcd arch : test05 gdt init failed\n");
goto fail_gdt;
}
if (lcd_arch_ept_gpa_to_hpa(lcd, LCD_ARCH_GDTR_BASE, &hpa)) {
printk(KERN_ERR "lcd arch : test04 lookup failed\n");
printk(KERN_ERR "lcd arch : test05 lookup failed\n");
goto fail_lookup;
}
if (hpa != __pa(lcd->gdt)) {
printk(KERN_ERR "lcd arch : test04 unexpected gdt addr\n");
printk(KERN_ERR "lcd arch : test05 unexpected gdt addr\n");
goto fail_lookup;
}
......@@ -312,30 +312,30 @@ fail_alloc:
return -1;
}
static int test05(void)
static int test06(void)
{
struct lcd_arch *lcd;
u64 hpa;
lcd = (struct lcd_arch *)kmalloc(sizeof(*lcd), GFP_KERNEL);
if (!lcd) {
printk(KERN_ERR "lcd arch : test05 failed to alloc lcd\n");
printk(KERN_ERR "lcd arch : test06 failed to alloc lcd\n");
goto fail_alloc;
}
if (vmx_init_ept(lcd)) {
printk(KERN_ERR "lcd arch : test05 ept init failed\n");
printk(KERN_ERR "lcd arch : test06 ept init failed\n");
goto fail_ept;
}
if (vmx_init_tss(lcd)) {
printk(KERN_ERR "lcd arch : test05 tss init failed\n");
printk(KERN_ERR "lcd arch : test06 tss init failed\n");
goto fail_tss;
}
if (lcd_arch_ept_gpa_to_hpa(lcd, LCD_ARCH_TSS_BASE, &hpa)) {
printk(KERN_ERR "lcd arch : test05 lookup failed\n");
printk(KERN_ERR "lcd arch : test06 lookup failed\n");
goto fail_lookup;
}
if (hpa != __pa(lcd->tss)) {
printk(KERN_ERR "lcd arch : test05 unexpected tss addr\n");
printk(KERN_ERR "lcd arch : test06 unexpected tss addr\n");
goto fail_lookup;
}
......@@ -352,30 +352,30 @@ fail_alloc:
return -1;
}
static int test06(void)
static int test07(void)
{
struct lcd_arch *lcd;
u64 hpa;
lcd = (struct lcd_arch *)kmalloc(sizeof(*lcd), GFP_KERNEL);
if (!lcd) {
printk(KERN_ERR "lcd arch : test06 failed to alloc lcd\n");
printk(KERN_ERR "lcd arch : test07 failed to alloc lcd\n");
goto fail_alloc;
}
if (vmx_init_ept(lcd)) {
printk(KERN_ERR "lcd arch : test06 ept init failed\n");
printk(KERN_ERR "lcd arch : test07 ept init failed\n");
goto fail_ept;
}
if (vmx_init_stack(lcd)) {
printk(KERN_ERR "lcd arch : test06 stack init failed\n");
printk(KERN_ERR "lcd arch : test07 stack init failed\n");
goto fail_stack;
}
if (lcd_arch_ept_gpa_to_hpa(lcd, LCD_ARCH_UTCB, &hpa)) {
printk(KERN_ERR "lcd arch : test06 lookup failed\n");
printk(KERN_ERR "lcd arch : test07 lookup failed\n");
goto fail_lookup;
}
if (hpa != __pa(lcd->utcb)) {
printk(KERN_ERR "lcd arch : test06 unexpected utcb addr\n");
printk(KERN_ERR "lcd arch : test07 unexpected utcb addr\n");
goto fail_lookup;
}
......@@ -392,20 +392,20 @@ fail_alloc:
return -1;
}
static int test07(void)
static int test08(void)
{
struct lcd_arch *lcd;
lcd = lcd_arch_create();
if (!lcd) {
printk(KERN_ERR "lcd arch : test07 failed to create lcd\n");
printk(KERN_ERR "lcd arch : test08 failed to create lcd\n");
return -1;
}
lcd_arch_destroy(lcd);
return 0;
}
#endif
static void lcd_arch_tests(void)
{
if (test01())
......@@ -416,14 +416,13 @@ static void lcd_arch_tests(void)
return;
if (test04())
return;
#if 0
if (test05())
return;
if (test06())
return;
if (test07())
return;
#endif
if (test08())
return;
return;
}
......@@ -1865,8 +1865,10 @@ static int vmx_init_gdt(struct lcd_arch *vcpu)
1,
/* no overwrite */
0);
if (ret)
if (ret) {
printk(KERN_ERR "vmx_gdt_init: failed to map gdt\n");
goto fail_map;
}
return 0;
......@@ -1932,8 +1934,10 @@ static int vmx_init_tss(struct lcd_arch *vcpu)
1,
/* no overwrite */
0);
if (ret)
if (ret) {
printk(KERN_ERR "vmx_init_tss: failed to map tss\n");
goto fail_map;
}
return 0;
......@@ -1976,8 +1980,10 @@ static int vmx_init_stack(struct lcd_arch *vcpu)
1,
/* no overwrite */
0);
if (ret)
if (ret) {
printk(KERN_ERR "vmx_init_stack: failed to map stack\n");
goto fail_map;
}
return 0;
......@@ -2057,18 +2063,26 @@ struct lcd_arch* lcd_arch_create(void)
* The EPT must be initialized before GDT, TSS, and stack,
* so that they can be mapped in guest physical.
*/
if (vmx_init_ept(vcpu))
if (vmx_init_ept(vcpu)) {
printk(KERN_ERR "lcd_arch_create: failed to init ept\n");
goto fail_ept;
if (vmx_init_gdt(vcpu))
}
if (vmx_init_gdt(vcpu)) {
printk(KERN_ERR "lcd_arch_create: failed to init gdt\n");
goto fail_gdt;
if (vmx_init_tss(vcpu))
}
if (vmx_init_tss(vcpu)) {
printk(KERN_ERR "lcd_arch_create: failed to init tss\n");
goto fail_tss;
}
/*
* Initialize stack / utcb
*/
if (vmx_init_stack(vcpu))
if (vmx_init_stack(vcpu)) {
printk(KERN_ERR "lcd_arch_create: failed to init stack\n");
goto fail_stack;
}
/*
* Initialize VMCS register values and settings
......@@ -2082,10 +2096,12 @@ struct lcd_arch* lcd_arch_create(void)
return vcpu;
fail_stack:
free_page((u64)vcpu->tss);
fail_tss:
free_page((u64)vcpu->gdt);
fail_gdt:
/*
* free ept will free gdt, tss, and stack, since they
* are mapped in ept
*/
vmx_free_ept(vcpu);
fail_ept:
vmx_free_vpid(vcpu);
......
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