diff options
author | Avi Kivity <avi@qumranet.com> | 2007-01-05 19:36:43 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2007-01-06 02:55:24 -0500 |
commit | cea0f0e7ea54753c3265dc77f605a6dad1912cfc (patch) | |
tree | e0a3e64b45fe83f1f0ae89556e1f6fcf92f07185 /drivers/kvm/kvm.h | |
parent | 25c0de2cc6c26cb99553c2444936a7951c120c09 (diff) |
[PATCH] KVM: MMU: Shadow page table caching
Define a hashtable for caching shadow page tables. Look up the cache on
context switch (cr3 change) or during page faults.
The key to the cache is a combination of
- the guest page table frame number
- the number of paging levels in the guest
* we can cache real mode, 32-bit mode, pae, and long mode page
tables simultaneously. this is useful for smp bootup.
- the guest page table table
* some kernels use a page as both a page table and a page directory. this
allows multiple shadow pages to exist for that page, one per level
- the "quadrant"
* 32-bit mode page tables span 4MB, whereas a shadow page table spans
2MB. similarly, a 32-bit page directory spans 4GB, while a shadow
page directory spans 1GB. the quadrant allows caching up to 4 shadow page
tables for one guest page in one level.
- a "metaphysical" bit
* for real mode, and for pse pages, there is no guest page table, so set
the bit to avoid write protecting the page.
Signed-off-by: Avi Kivity <avi@qumranet.com>
Acked-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/kvm/kvm.h')
-rw-r--r-- | drivers/kvm/kvm.h | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h index abe40dd34eea..58b9deb0bc0e 100644 --- a/drivers/kvm/kvm.h +++ b/drivers/kvm/kvm.h | |||
@@ -89,14 +89,53 @@ typedef unsigned long hva_t; | |||
89 | typedef u64 hpa_t; | 89 | typedef u64 hpa_t; |
90 | typedef unsigned long hfn_t; | 90 | typedef unsigned long hfn_t; |
91 | 91 | ||
92 | #define NR_PTE_CHAIN_ENTRIES 5 | ||
93 | |||
94 | struct kvm_pte_chain { | ||
95 | u64 *parent_ptes[NR_PTE_CHAIN_ENTRIES]; | ||
96 | struct hlist_node link; | ||
97 | }; | ||
98 | |||
99 | /* | ||
100 | * kvm_mmu_page_role, below, is defined as: | ||
101 | * | ||
102 | * bits 0:3 - total guest paging levels (2-4, or zero for real mode) | ||
103 | * bits 4:7 - page table level for this shadow (1-4) | ||
104 | * bits 8:9 - page table quadrant for 2-level guests | ||
105 | * bit 16 - "metaphysical" - gfn is not a real page (huge page/real mode) | ||
106 | */ | ||
107 | union kvm_mmu_page_role { | ||
108 | unsigned word; | ||
109 | struct { | ||
110 | unsigned glevels : 4; | ||
111 | unsigned level : 4; | ||
112 | unsigned quadrant : 2; | ||
113 | unsigned pad_for_nice_hex_output : 6; | ||
114 | unsigned metaphysical : 1; | ||
115 | }; | ||
116 | }; | ||
117 | |||
92 | struct kvm_mmu_page { | 118 | struct kvm_mmu_page { |
93 | struct list_head link; | 119 | struct list_head link; |
120 | struct hlist_node hash_link; | ||
121 | |||
122 | /* | ||
123 | * The following two entries are used to key the shadow page in the | ||
124 | * hash table. | ||
125 | */ | ||
126 | gfn_t gfn; | ||
127 | union kvm_mmu_page_role role; | ||
128 | |||
94 | hpa_t page_hpa; | 129 | hpa_t page_hpa; |
95 | unsigned long slot_bitmap; /* One bit set per slot which has memory | 130 | unsigned long slot_bitmap; /* One bit set per slot which has memory |
96 | * in this shadow page. | 131 | * in this shadow page. |
97 | */ | 132 | */ |
98 | int global; /* Set if all ptes in this page are global */ | 133 | int global; /* Set if all ptes in this page are global */ |
99 | u64 *parent_pte; | 134 | int multimapped; /* More than one parent_pte? */ |
135 | union { | ||
136 | u64 *parent_pte; /* !multimapped */ | ||
137 | struct hlist_head parent_ptes; /* multimapped, kvm_pte_chain */ | ||
138 | }; | ||
100 | }; | 139 | }; |
101 | 140 | ||
102 | struct vmcs { | 141 | struct vmcs { |
@@ -235,7 +274,11 @@ struct kvm { | |||
235 | spinlock_t lock; /* protects everything except vcpus */ | 274 | spinlock_t lock; /* protects everything except vcpus */ |
236 | int nmemslots; | 275 | int nmemslots; |
237 | struct kvm_memory_slot memslots[KVM_MEMORY_SLOTS]; | 276 | struct kvm_memory_slot memslots[KVM_MEMORY_SLOTS]; |
277 | /* | ||
278 | * Hash table of struct kvm_mmu_page. | ||
279 | */ | ||
238 | struct list_head active_mmu_pages; | 280 | struct list_head active_mmu_pages; |
281 | struct hlist_head mmu_page_hash[KVM_NUM_MMU_PAGES]; | ||
239 | struct kvm_vcpu vcpus[KVM_MAX_VCPUS]; | 282 | struct kvm_vcpu vcpus[KVM_MAX_VCPUS]; |
240 | int memory_config_version; | 283 | int memory_config_version; |
241 | int busy; | 284 | int busy; |