Commit 2f888fcc authored by Bandan Das's avatar Bandan Das Committed by Paolo Bonzini
Browse files

VMX: check for supported contexts before calling invept



It's incorrect to assume the context in which invept
is called. Check what is supported and fallback if
single context invalidation isn't supported

Signed-off-by: default avatarBandan Das <bsd@redhat.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 03298f10
......@@ -288,6 +288,26 @@ unsigned long get_ept_pte(unsigned long *pml4,
return pte;
}
void ept_sync(int type, u64 eptp)
{
switch (type) {
case INVEPT_SINGLE:
if (ept_vpid.val & EPT_CAP_INVEPT_SINGLE) {
invept(INVEPT_SINGLE, eptp);
break;
}
/* else fall through */
case INVEPT_GLOBAL:
if (ept_vpid.val & EPT_CAP_INVEPT_ALL) {
invept(INVEPT_GLOBAL, eptp);
break;
}
/* else fall through */
default:
printf("WARNING: invept is not supported!\n");
}
}
int set_ept_pte(unsigned long *pml4, unsigned long guest_addr,
int level, u64 pte_val)
{
......
......@@ -551,6 +551,7 @@ static inline void invept(unsigned long type, u64 eptp)
}
void print_vmexit_info();
void ept_sync(int type, u64 eptp);
void install_ept_entry(unsigned long *pml4, int pte_level,
unsigned long guest_addr, unsigned long pte,
unsigned long *pt_page);
......
......@@ -1116,21 +1116,21 @@ static int ept_exit_handler()
case 1:
install_ept(pml4, (unsigned long)data_page1,
(unsigned long)data_page1, EPT_WA);
invept(INVEPT_SINGLE, eptp);
ept_sync(INVEPT_SINGLE, eptp);
break;
case 2:
install_ept(pml4, (unsigned long)data_page1,
(unsigned long)data_page1,
EPT_RA | EPT_WA | EPT_EA |
(2 << EPT_MEM_TYPE_SHIFT));
invept(INVEPT_SINGLE, eptp);
ept_sync(INVEPT_SINGLE, eptp);
break;
case 3:
data_page1_pte = get_ept_pte(pml4,
(unsigned long)data_page1, 1);
set_ept_pte(pml4, (unsigned long)data_page1,
1, data_page1_pte & (~EPT_PRESENT));
invept(INVEPT_SINGLE, eptp);
ept_sync(INVEPT_SINGLE, eptp);
break;
case 4:
data_page1_pte = get_ept_pte(pml4,
......@@ -1139,7 +1139,7 @@ static int ept_exit_handler()
data_page1_pte_pte = get_ept_pte(pml4, data_page1_pte, 2);
set_ept_pte(pml4, data_page1_pte, 2,
data_page1_pte_pte & (~EPT_PRESENT));
invept(INVEPT_SINGLE, eptp);
ept_sync(INVEPT_SINGLE, eptp);
break;
// Should not reach here
default:
......@@ -1157,7 +1157,7 @@ static int ept_exit_handler()
install_ept(pml4, (unsigned long)data_page1,
(unsigned long)data_page1,
EPT_RA | EPT_WA | EPT_EA);
invept(INVEPT_SINGLE, eptp);
ept_sync(INVEPT_SINGLE, eptp);
break;
// Should not reach here
default:
......@@ -1174,14 +1174,14 @@ static int ept_exit_handler()
set_stage(get_stage() + 1);
set_ept_pte(pml4, (unsigned long)data_page1,
1, data_page1_pte | (EPT_PRESENT));
invept(INVEPT_SINGLE, eptp);
ept_sync(INVEPT_SINGLE, eptp);
break;
case 4:
if (exit_qual == (EPT_VLT_RD | EPT_VLT_LADDR_VLD))
set_stage(get_stage() + 1);
set_ept_pte(pml4, data_page1_pte, 2,
data_page1_pte_pte | (EPT_PRESENT));
invept(INVEPT_SINGLE, eptp);
ept_sync(INVEPT_SINGLE, eptp);
break;
default:
// Should not reach here
......
Supports Markdown
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