Commit f9b52a46 authored by Charlie Jacobsen's avatar Charlie Jacobsen Committed by Vikram Narayanan

Shifted gpa map / unmap range to arch-dep code.

Updated tests.
parent 8a977687
......@@ -189,10 +189,31 @@ int lcd_arch_ept_unset(lcd_arch_epte_t *epte);
*/
int lcd_arch_ept_map_gpa_to_hpa(struct lcd_arch *vcpu, u64 gpa, u64 hpa,
int create, int overwrite);
/**
* Maps
*
* gpa_start --> gpa_start + npages * PAGE_SIZE
*
* to
*
* hpa_start --> hpa_start + npages * PAGE_SIZE
*
* in lcd's ept.
*/
int lcd_arch_ept_map_range(struct lcd_arch *lcd, u64 gpa_start, u64 hpa_start,
u64 npages);
/**
* Simple routine combining ept walk and unset.
*/
int lcd_arch_ept_unmap_gpa(struct lcd_arch *vcpu, u64 gpa);
/**
* Unmaps
*
* gpa_start --> gpa_start + npages * PAGE_SIZE
*
* in lcd's ept.
*/
int lcd_arch_ept_unmap_range(struct lcd_arch *lcd, u64 gpa_start, u64 npages);
/**
* Simple routine combinding ept walk and get.
*/
......
......@@ -103,57 +103,36 @@ static int test04(void)
lcd = (struct lcd_arch *)kmalloc(sizeof(*lcd), GFP_KERNEL);
if (!lcd) {
printk(KERN_ERR "lcd arch : test04 failed to alloc lcd\n");
goto fail_alloc;
goto fail1;
}
if (vmx_init_ept(lcd)) {
printk(KERN_ERR "lcd arch : test04 ept init failed\n");
goto fail;
goto fail2;
}
/*
* Map 0x0 - 0x400000 (first 4 MBs, takes two page dirs)
*/
base = 0;
for (off = 0; off < 0x40000; off += PAGE_SIZE) {
if (lcd_arch_ept_map_gpa_to_hpa(lcd, base + off,
base + off,
1,
0)) {
printk(KERN_ERR "lcd arch : test04 failed to map %lx\n",
(unsigned long)(base + off));
goto fail_map;
}
if (lcd_arch_ept_map_range(lcd, 0, 0, 1024)) {
printk(KERN_ERR "lcd arch: test04 failed to map first 4 MBs\n");
goto fail3;
}
/*
* Map 0x40000000 - 0x40400000 (1GB -- 1GB + 4MBs, takes two page dirs)
*/
base = 0x40000000;
for (off = 0; off < 0x40000; off += PAGE_SIZE) {
if (lcd_arch_ept_map_gpa_to_hpa(lcd, base + off,
base + off,
1,
0)) {
printk(KERN_ERR "lcd arch : test04 failed to map %lx\n",
(unsigned long)(base + off));
goto fail_map;
}
if (lcd_arch_ept_map_range(lcd, 1 << 30, 1 << 30, 1024)) {
printk(KERN_ERR "lcd arch: test04 failed to map 2nd 4 MBs\n");
goto fail4;
}
/*
* Map 0x8000000000 - 0x8000400000 (512GB -- 512GB + 4MBs,
* takes two page dirs)
*/
base = 0x8000000000;
for (off = 0; off < 0x40000; off += PAGE_SIZE) {
if (lcd_arch_ept_map_gpa_to_hpa(lcd, base + off,
base + off,
1,
0)) {
printk(KERN_ERR "lcd arch : test04 failed to map %lx\n",
(unsigned long)(base + off));
goto fail_map;
}
if (lcd_arch_ept_map_range(lcd, 1 << 39, 1 << 39, 1024)) {
printk(KERN_ERR "lcd arch: test04 failed to map 3rd 4 MBs\n");
goto fail5;
}
/*
......@@ -165,14 +144,14 @@ static int test04(void)
if (lcd_arch_ept_gpa_to_hpa(lcd, base + off, &actual)) {
printk(KERN_ERR "lcd arch : test04 failed lookup at %lx\n",
(unsigned long)(base + off));
goto fail_map;
goto fail6;
}
if (actual != (base + off)) {
printk(KERN_ERR "lcd arch : test04 expected hpa %lx got %lx\n",
(unsigned long)(base + off),
(unsigned long)actual);
goto fail_map;
goto fail6;
}
}
......@@ -181,14 +160,14 @@ static int test04(void)
if (lcd_arch_ept_gpa_to_hpa(lcd, base + off, &actual)) {
printk(KERN_ERR "lcd arch : test04 failed lookup at %lx\n",
(unsigned long)(base + off));
goto fail_map;
goto fail6;
}
if (actual != (base + off)) {
printk(KERN_ERR "lcd arch : test04 expected hpa %lx got %lx\n",
(unsigned long)(base + off),
(unsigned long)actual);
goto fail_map;
goto fail6;
}
}
......@@ -197,27 +176,36 @@ static int test04(void)
if (lcd_arch_ept_gpa_to_hpa(lcd, base + off, &actual)) {
printk(KERN_ERR "lcd arch : test04 failed lookup at %lx\n",
(unsigned long)(base + off));
goto fail_map;
goto fail6;
}
if (actual != (base + off)) {
printk(KERN_ERR "lcd arch : test04 expected hpa %lx got %lx\n",
(unsigned long)(base + off),
(unsigned long)actual);
goto fail_map;
goto fail6;
}
}
lcd_arch_ept_unmap_range(lcd, 1 << 39, 1 << 39, 1024);
lcd_arch_ept_unmap_range(lcd, 1 << 30, 1 << 30, 1024);
lcd_arch_ept_unmap_range(lcd, 0, 0, 1024);
vmx_free_ept(lcd);
kfree(lcd);
return 0;
fail_map:
fail6:
lcd_arch_ept_unmap_range(lcd, 1 << 39, 1 << 39, 1024);
fail5:
lcd_arch_ept_unmap_range(lcd, 1 << 30, 1 << 30, 1024);
fail4:
lcd_arch_ept_unmap_range(lcd, 0, 0, 1024);
fail3:
vmx_free_ept(lcd);
fail:
fail2:
kfree(lcd);
fail_alloc:
fail1:
return -1;
}
......
......@@ -1052,6 +1052,33 @@ int lcd_arch_ept_map_gpa_to_hpa(struct lcd_arch *vcpu, u64 gpa, u64 hpa,
return 0;
}
int lcd_arch_ept_map_range(struct lcd_arch *lcd, u64 gpa_start, u64 hpa_start,
u64 npages)
{
u64 off;
u64 len;
len = npages * PAGE_SIZE;
for (off = 0; off < len; off += PAGE_SIZE) {
if (lcd_arch_ept_map_gpa_to_hpa(lcd,
/* gpa */
gpa_start + off,
/* hpa */
hpa_start + off,
/* create */
1,
/* no overwrite */
0)) {
printk(KERN_ERR "lcd_arch_ept_map_range: error mapping gpa %lx to hpa %lx\n",
(unsigned long)(gpa_start + off),
(unsigned long)(hpa_start + off));
return -EIO;
}
}
return 0;
}
int lcd_arch_ept_unmap_gpa(struct lcd_arch *vcpu, u64 gpa)
{
int ret;
......@@ -1072,6 +1099,29 @@ int lcd_arch_ept_unmap_gpa(struct lcd_arch *vcpu, u64 gpa)
return 0;
}
/**
* Unmaps
*
* gpa_start --> gpa_start + npages * PAGE_SIZE
*
* in lcd's ept.
*/
int lcd_arch_ept_unmap_range(struct lcd_arch *lcd, u64 gpa_start, u64 npages)
{
u64 off;
u64 len;
len = npages * PAGE_SIZE;
for (off = 0; off < len; off += PAGE_SIZE) {
if (lcd_arch_ept_unmap_gpa(lcd, gpa_start + off)) {
printk(KERN_ERR "lcd_arch_ept_unmap_range: error unmapping gpa %lx\n",
(unsigned long)(gpa_start + off));
return -EIO;
}
}
return 0;
}
int lcd_arch_ept_gpa_to_hpa(struct lcd_arch *vcpu, u64 gpa, u64 *hpa_out)
{
......@@ -2697,8 +2747,10 @@ EXPORT_SYMBOL(lcd_arch_ept_walk);
EXPORT_SYMBOL(lcd_arch_ept_set);
EXPORT_SYMBOL(lcd_arch_ept_unset);
EXPORT_SYMBOL(lcd_arch_ept_unmap_gpa);
EXPORT_SYMBOL(lcd_arch_ept_unmap_range);
EXPORT_SYMBOL(lcd_arch_ept_hpa);
EXPORT_SYMBOL(lcd_arch_ept_map_gpa_to_hpa);
EXPORT_SYMBOL(lcd_arch_ept_map_range);
EXPORT_SYMBOL(lcd_arch_ept_gpa_to_hpa);
EXPORT_SYMBOL(lcd_arch_set_pc);
EXPORT_SYMBOL(lcd_arch_set_gva_root);
......
......@@ -26,70 +26,6 @@
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("LCD driver");
/* Guest Physical ---------------------------------------- */
/**
* Maps
*
* gpa_start --> gpa_start + npages * PAGE_SIZE
*
* to
*
* hpa_start --> hpa_start + npages * PAGE_SIZE
*
* in lcd's ept.
*/
static int lcd_mm_gpa_map_range(struct lcd *lcd, u64 gpa_start, u64 hpa_start,
u64 npages)
{
u64 off;
u64 len;
len = npages * PAGE_SIZE;
for (off = 0; off < len; off += PAGE_SIZE) {
if (lcd_arch_ept_map_gpa_to_hpa(lcd->lcd_arch,
/* gpa */
gpa_start + off,
/* hpa */
hpa_start + off,
/* create */
1,
/* no overwrite */
0)) {
printk(KERN_ERR "lcd_mm_gpa_map_range: error mapping gpa %lx to hpa %lx\n",
(unsigned long)(gpa_start + off),
(unsigned long)(hpa_start + off));
return -EIO;
}
}
return 0;
}
/**
* Unmaps
*
* gpa_start --> gpa_start + npages * PAGE_SIZE
*
* in lcd's ept.
*/
static int lcd_mm_gpa_unmap_range(struct lcd *lcd, u64 gpa_start, u64 npages)
{
u64 off;
u64 len;
len = npages * PAGE_SIZE;
for (off = 0; off < len; off += PAGE_SIZE) {
if (lcd_arch_ept_unmap_gpa(lcd->lcd_arch, gpa_start + off)) {
printk(KERN_ERR "lcd_mm_gpa_unmap_range: error unmapping gpa %lx\n",
(unsigned long)(gpa_start + off));
return -EIO;
}
}
return 0;
}
/* Guest Virtual -------------------------------------------------- */
/**
......@@ -133,7 +69,7 @@ static int lcd_mm_gva_init(struct lcd *lcd, u64 gv_paging_mem_start_gpa,
/*
* Map global page dir's page in lcd's ept
*/
ret = lcd_mm_gpa_map_range(lcd, gv_paging_mem_start_gpa, root, 1);
ret = lcd_arch_ept_map_range(lcd, gv_paging_mem_start_gpa, root, 1);
if (ret) {
printk("lcd_mm_gva_init: error mapping global page dir\n");
goto fail3;
......@@ -173,7 +109,7 @@ static int lcd_mm_pt_destroy(struct lcd *lcd, pmd_t *pmd_entry)
/*
* Unmap page table
*/
ret = lcd_mm_gpa_unmap_range(lcd, gpa, 1);
ret = lcd_arch_ept_unmap_range(lcd, gpa, 1);
if (ret) {
printk(KERN_ERR "lcd_mm_pt_destroy: error unmapping pt\n");
return ret;
......@@ -224,7 +160,7 @@ static int lcd_mm_pmd_destroy(struct lcd *lcd, pud_t *pud_entry)
/*
* Unmap pmd
*/
ret = lcd_mm_gpa_unmap_range(lcd, gpa, 1);
ret = lcd_arch_ept_unmap_range(lcd, gpa, 1);
if (ret) {
printk(KERN_ERR "lcd_mm_pmd_destroy: error unmapping pmd\n");
return ret;
......@@ -275,7 +211,7 @@ static int lcd_mm_pud_destroy(struct lcd *lcd, pgd_t *pgd_entry)
/*
* Unmap pud
*/
ret = lcd_mm_gpa_unmap_range(lcd, gpa, 1);
ret = lcd_arch_ept_unmap_range(lcd, gpa, 1);
/*
* Free pud
......@@ -317,7 +253,7 @@ static void lcd_mm_gva_destroy(struct lcd *lcd)
/*
* Unmap in ept
*/
ret = lcd_mm_gpa_unmap_range(lcd, lcd->gv.paging_mem_bot, 1);
ret = lcd_arch_ept_unmap_range(lcd, lcd->gv.paging_mem_bot, 1);
if (ret) {
printk(KERN_ERR "lcd_mm_gva_destroy: error unmapping pgd\n");
return;
......@@ -370,7 +306,7 @@ static int lcd_mm_gva_alloc(struct lcd *lcd, u64 *gpa, u64 *hpa)
/*
* Map in ept
*/
ret = lcd_mm_gpa_map_range(lcd, *gpa, *hpa, 1);
ret = lcd_arch_ept_map_range(lcd, *gpa, *hpa, 1);
if (ret) {
printk(KERN_ERR "lcd_mm_gva_alloc: couldn't map gpa %lx to hpa %lx\n",
(unsigned long)*gpa,
......@@ -958,7 +894,7 @@ static int lcd_init_blob(struct lcd *lcd, unsigned char *blob,
/*
* Map blob in guest physical, after paging mem
*/
r = lcd_mm_gpa_map_range(lcd, LCD_ARCH_FREE + paging_mem_size,
r = lcd_arch_ept_map_range(lcd, LCD_ARCH_FREE + paging_mem_size,
__pa((u64)blob), (1 << blob_order));
if (r) {
printk(KERN_ERR "lcd_init_blob: error mapping blob in gpa\n");
......@@ -997,7 +933,7 @@ static int lcd_init_blob(struct lcd *lcd, unsigned char *blob,
fail4:
/* gva destroy will handle clean up after this failure */
fail3:
lcd_mm_gpa_unmap_range(lcd, LCD_ARCH_FREE + paging_mem_size,
lcd_arch_ept_unmap_range(lcd, LCD_ARCH_FREE + paging_mem_size,
(1 << blob_order));
fail2:
lcd_mm_gva_destroy(lcd);
......
......@@ -90,7 +90,7 @@ static int test03(void)
}
free_page((u64)__va(hpa));
lcd_mm_gpa_unmap_range(lcd, gpa, 1);
lcd_arch_ept_unmap_range(lcd, gpa, 1);
lcd_destroy(lcd);
......@@ -98,7 +98,7 @@ static int test03(void)
fail4:
free_page((u64)__va(hpa));
lcd_mm_gpa_unmap_range(lcd, gpa, 1);
lcd_arch_ept_unmap_range(lcd, gpa, 1);
fail3:
fail2:
lcd_destroy(lcd);
......@@ -167,7 +167,7 @@ static int test04(void)
}
free_page((u64)__va(hpa));
lcd_mm_gpa_unmap_range(lcd, gpa, 1);
lcd_arch_ept_unmap_range(lcd, gpa, 1);
kfree(pmd_entry);
lcd_destroy(lcd);
......@@ -179,7 +179,7 @@ fail5:
kfree(pmd_entry);
fail4:
free_page((u64)__va(hpa));
lcd_mm_gpa_unmap_range(lcd, gpa, 1);
lcd_arch_ept_unmap_range(lcd, gpa, 1);
fail3:
fail2:
lcd_destroy(lcd);
......@@ -250,7 +250,7 @@ static int test05(void)
}
free_page((u64)__va(hpa));
lcd_mm_gpa_unmap_range(lcd, gpa, 1);
lcd_arch_ept_unmap_range(lcd, gpa, 1);
kfree(pud_entry);
lcd_destroy(lcd);
......@@ -262,7 +262,7 @@ fail5:
kfree(pud_entry);
fail4:
free_page((u64)__va(hpa));
lcd_mm_gpa_unmap_range(lcd, gpa, 1);
lcd_arch_ept_unmap_range(lcd, gpa, 1);
fail3:
fail2:
lcd_destroy(lcd);
......@@ -333,7 +333,7 @@ static int test06(void)
}
free_page((u64)__va(hpa));
lcd_mm_gpa_unmap_range(lcd, gpa, 1);
lcd_arch_ept_unmap_range(lcd, gpa, 1);
kfree(pgd_entry);
lcd_destroy(lcd);
......@@ -345,7 +345,7 @@ fail5:
kfree(pgd_entry);
fail4:
free_page((u64)__va(hpa));
lcd_mm_gpa_unmap_range(lcd, gpa, 1);
lcd_arch_ept_unmap_range(lcd, gpa, 1);
fail3:
fail2:
lcd_destroy(lcd);
......@@ -409,6 +409,59 @@ fail1:
return ret;
}
static int test08(void)
{
struct lcd *lcd;
int ret;
u64 gpa;
pgd_t *pgd_entry1;
pgd_t *pgd_entry2;
ret = lcd_create(&lcd);
if (ret) {
printk(KERN_ERR "lcd test: test08 failed to create lcd\n");
goto fail1;
}
ret = lcd_mm_gva_init(lcd, LCD_ARCH_FREE,
LCD_ARCH_FREE + 4 * (1 << 20));
if (ret) {
printk(KERN_ERR "lcd test: test08 failed to init gva\n");
goto fail2;
}
ret = lcd_mm_gva_walk_pgd(lcd, 0x1234000UL, &pgd_entry1);
if (ret) {
printk(KERN_ERR "lcd test: test08 failed to walk pgd\n");
goto fail3;
}
ret = lcd_mm_gva_walk_pgd(lcd, 0x1234000UL, &pgd_entry2);
if (ret) {
printk(KERN_ERR "lcd test: test08 failed to walk pgd2\n");
goto fail4;
}
if (pgd_entry1 != pgd_entry2) {
printk(KERN_ERR "lcd test: test08 entries differ\n");
ret = -1;
goto fail5;
}
lcd_destroy(lcd);
return 0;
fail5:
fail4:
fail3:
fail2:
lcd_destroy(lcd);
fail1:
return ret;
}
#if 0
static int test08(void)
{
struct lcd *lcd;
......@@ -520,6 +573,7 @@ fail2:
fail1:
return ret;
}
#endif
static void lcd_tests(void)
{
......
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