KVM: MMU: Add EPT support
PATCH 4/8 KVM: MMU: Add EPT support
From 239f38236196c2321989c64d7c61ff28490b3f00 Mon Sep 17 00:00:00 2001
From: Sheng Yang <[email protected]>
Date: Fri, 25 Apr 2008 21:13:50 +0800
Subject: [PATCH 4/8] KVM: MMU: Add EPT support
Enable kvm_set_spte() to generate EPT entries.
--- arch/x86/kvm/mmu.c | 47 ++++++++++++++++++++++++++++++++----------- arch/x86/kvm/x86.c | 3 ++ include/asm-x86/kvm_host.h | 3 ++ 3 files changed, 41 insertions(+), 12 deletions(-)
arch/x86/kvm/mmu.c +6 -0
@@ -152,6 +152,12 @@ static struct kmem_cache *mmu_page_header_cache;static u64 __read_mostly shadow_trap_nonpresent_pte;static u64 __read_mostly shadow_notrap_nonpresent_pte; +static u64 __read_mostly shadow_base_present_pte; +static u64 __read_mostly shadow_nx_mask; +static u64 __read_mostly shadow_x_mask;/* mutual exclusive with nx_mask */ +static u64 __read_mostly shadow_user_mask; +static u64 __read_mostly shadow_accessed_mask; +static u64 __read_mostly shadow_dirty_mask;void kvm_mmu_set_nonpresent_ptes (u64 trap_pte,u64 notrap_pte) {
@@ -160,6 +166,23 @@ void kvm_mmu_set_nonpresent_ptes(u64 trap_pte, u64
notrap_pte)
}
EXPORT_SYMBOL_GPL(kvm_mmu_set_nonpresent_ptes);
+void kvm_mmu_set_base_ptes(u64 base_pte)
+{
+ shadow_base_present_pte = base_pte;
+}
+EXPORT_SYMBOL_GPL(kvm_mmu_set_base_ptes);
+
+void kvm_mmu_set_mask_ptes(u64 user_mask, u64 accessed_mask,
+ u64 dirty_mask, u64 nx_mask, u64 x_mask)
+{
+ shadow_user_mask = user_mask;
+ shadow_accessed_mask = accessed_mask;
+ shadow_dirty_mask = dirty_mask;
+ shadow_nx_mask = nx_mask;
+ shadow_x_mask = x_mask;
+}
+EXPORT_SYMBOL_GPL(kvm_mmu_set_mask_ptes);
+
static int is_write_protection(struct kvm_vcpu *vcpu) {
return vcpu->arch.cr0 & X86_CR0_WP;
@@ -198,7 +221,7 @@ static int is_writeble_pte(unsigned long pte)
static int is_dirty_pte(unsigned long pte)
{
- return pte & PT_DIRTY_MASK;
+ return pte & shadow_dirty_mask;
}
static int is_rmap_pte(u64 pte)
@@ -513,7 +536,7 @@ static void rmap_remove(struct kvm *kvm, u64 *spte)
return;
sp = page_header(__pa(spte));
pfn = spte_to_pfn(*spte);
- if (*spte & PT_ACCESSED_MASK)
+ if (*spte & shadow_accessed_mask)
kvm_set_pfn_accessed(pfn);
if (is_writeble_pte(*spte))
kvm_release_pfn_dirty(pfn);
@@ -1039,17 +1062,17 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
* whether the guest actually used the pte (in order to detect
* demand paging).
*/
- spte = PT_PRESENT_MASK | PT_DIRTY_MASK;
+ spte = shadow_base_present_pte | shadow_dirty_mask;
if (!speculative)
pte_access |= PT_ACCESSED_MASK;
if (!dirty)
pte_access &= ~ACC_WRITE_MASK;
- if (!(pte_access & ACC_EXEC_MASK))
- spte |= PT64_NX_MASK;
-
- spte |= PT_PRESENT_MASK;
+ if (pte_access & ACC_EXEC_MASK)
+ spte |= shadow_x_mask;
+ else
+ spte |= shadow_nx_mask;
if (pte_access & ACC_USER_MASK)
- spte |= PT_USER_MASK;
+ spte |= shadow_user_mask;
if (largepage)
spte |= PT_PAGE_SIZE_MASK;
@@ -1155,7 +1178,7 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
}
table[index] = __pa(new_table->spt) | PT_PRESENT_MASK
- | PT_WRITABLE_MASK | PT_USER_MASK; + | PT_WRITABLE_MASK | shadow_user_mask;
}
table_addr = table[index] & PT64_BASE_ADDR_MASK;
}
@@ -1343,7 +1366,7 @@ static int tdp_page_fault(struct kvm_vcpu *vcpu, gva_t gpa,
spin_lock(&vcpu->kvm->mmu_lock); kvm_mmu_free_some_pages(vcpu);
r = __direct_map(vcpu, gpa, error_code & PFERR_WRITE_MASK,
- largepage, gfn, pfn, TDP_ROOT_LEVEL);
+ largepage, gfn, pfn, kvm_x86_ops->get_tdp_level());
spin_unlock(&vcpu->kvm->mmu_lock);
return r;
@@ -1450,7 +1473,7 @@ static int init_kvm_tdp_mmu(struct kvm_vcpu *vcpu)
context->page_fault = tdp_page_fault;
context->free = nonpaging_free; context->prefetch_page = nonpaging_prefetch_page;
- context->shadow_root_level = TDP_ROOT_LEVEL;
+ context->shadow_root_level = kvm_x86_ops->get_tdp_level();
context->root_hpa = INVALID_PAGE;
if (!is_paging(vcpu)) {
@@ -1599,7 +1622,7 @@ static bool last_updated_pte_accessed(struct kvm_vcpu *vcpu)
{
u64 *spte = vcpu->arch.last_pte_updated;
- return !!(spte && (*spte & PT_ACCESSED_MASK));
+ return !!(spte && (*spte & shadow_accessed_mask));
}
static void mmu_guess_page_from_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
arch/x86/kvm/x86.c +3 -0
@@ -2417,6 +2417,9 @@ int kvm_arch_init(void *opaque) kvm_x86_ops = ops;kvm_mmu_set_nonpresent_ptes (0ull ,0ull ); +kvm_mmu_set_base_ptes (PT_PRESENT_MASK ); +kvm_mmu_set_mask_ptes (PT_USER_MASK ,PT_ACCESSED_MASK , +PT_DIRTY_MASK ,PT64_NX_MASK ,0 );return 0 ; out:
include/asm-x86/kvm_host.h +3 -0
@@ -433,6 +433,9 @@ void kvm_mmu_destroy(struct kvm_vcpu *vcpu);int kvm_mmu_create (struct kvm_vcpu *vcpu);int kvm_mmu_setup (struct kvm_vcpu *vcpu);void kvm_mmu_set_nonpresent_ptes (u64 trap_pte,u64 notrap_pte); +void kvm_mmu_set_base_ptes (u64 base_pte); +void kvm_mmu_set_mask_ptes (u64 user_mask,u64 accessed_mask, +u64 dirty_mask,u64 nx_mask,u64 x_mask);int kvm_mmu_reset_context (struct kvm_vcpu *vcpu);void kvm_mmu_slot_remove_write_access (struct kvm *kvm,int slot);
--
1.5.4.5
From 239f38236196c2321989c64d7c61ff28490b3f00 Mon Sep 17 00:00:00 2001
From: Sheng Yang <[email protected]>
Date: Fri, 25 Apr 2008 21:13:50 +0800
Subject: [PATCH 4/8] KVM: MMU: Add EPT support
Enable kvm_set_spte() to generate EPT entries.
--- arch/x86/kvm/mmu.c | 47 ++++++++++++++++++++++++++++++++----------- arch/x86/kvm/x86.c | 3 ++ include/asm-x86/kvm_host.h | 3 ++ 3 files changed, 41 insertions(+), 12 deletions(-)
arch/x86/kvm/mmu.c +35 -12
106 lines not on this page · raw message
arch/x86/kvm/x86.c +3 -0
@@ -2417,6 +2417,9 @@ int kvm_arch_init(void *opaque) kvm_x86_ops = ops;kvm_mmu_set_nonpresent_ptes (0ull ,0ull ); +kvm_mmu_set_base_ptes (PT_PRESENT_MASK ); +kvm_mmu_set_mask_ptes (PT_USER_MASK ,PT_ACCESSED_MASK , +PT_DIRTY_MASK ,PT64_NX_MASK ,0 );return 0 ; out:
include/asm-x86/kvm_host.h +3 -0
@@ -433,6 +433,9 @@ void kvm_mmu_destroy(struct kvm_vcpu *vcpu);int kvm_mmu_create (struct kvm_vcpu *vcpu);int kvm_mmu_setup (struct kvm_vcpu *vcpu);void kvm_mmu_set_nonpresent_ptes (u64 trap_pte,u64 notrap_pte); +void kvm_mmu_set_base_ptes (u64 base_pte); +void kvm_mmu_set_mask_ptes (u64 user_mask,u64 accessed_mask, +u64 dirty_mask,u64 nx_mask,u64 x_mask);int kvm_mmu_reset_context (struct kvm_vcpu *vcpu);void kvm_mmu_slot_remove_write_access (struct kvm *kvm,int slot);
Signature · 1 line
1.5.4.5
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference Don't miss this year's exciting event. There's still time to save $100. Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
kvm-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/kvm-devel
Quoted 9 lines · Sheng
From
239f38236196c2321989c64d7c61ff28490b3f00Mon Sep 17 00:00:00 2001
From: Sheng Yang <[email protected]>
Date: Fri, 25 Apr 2008 21:13:50 +0800
Subject: [PATCH 4/8] KVM: MMU: Add EPT supportEnable
kvm_set_spte()to generate EPT entries.
arch/x86/kvm/mmu.c static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, · line 1184
Quoted 8 lines
arch/x86/kvm/mmu.c +1
-1@@ -1155,7 +1178,7 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v,int write, } table[index] =__pa (new_table->spt) |PT_PRESENT_MASK - |PT_WRITABLE_MASK |PT_USER_MASK ; + |PT_WRITABLE_MASK | shadow_user_mask; }
Shouldn't we have shadow_x_mask here as well?
[and for non-EPT, shadow_accessed_mask and shadow_dirty_mask, but that's a different story].
Signature · 8 lines
error compiling committee.c: too many arguments to function ------------------------------------------------------------------------- This SF.net email is sponsored by the 2008 JavaOne(SM) Conference Don't miss this year's exciting event. There's still time to save $100. Use priority code J8TL2D2. http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone