diff options
Diffstat (limited to 'drivers/kvm/mmu.c')
-rw-r--r-- | drivers/kvm/mmu.c | 51 |
1 files changed, 17 insertions, 34 deletions
diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c index 23965aa5ee78..6d84d30f5ed0 100644 --- a/drivers/kvm/mmu.c +++ b/drivers/kvm/mmu.c | |||
@@ -158,7 +158,7 @@ static struct kmem_cache *mmu_page_header_cache; | |||
158 | 158 | ||
159 | static int is_write_protection(struct kvm_vcpu *vcpu) | 159 | static int is_write_protection(struct kvm_vcpu *vcpu) |
160 | { | 160 | { |
161 | return vcpu->cr0 & CR0_WP_MASK; | 161 | return vcpu->cr0 & X86_CR0_WP; |
162 | } | 162 | } |
163 | 163 | ||
164 | static int is_cpuid_PSE36(void) | 164 | static int is_cpuid_PSE36(void) |
@@ -202,15 +202,14 @@ static void set_shadow_pte(u64 *sptep, u64 spte) | |||
202 | } | 202 | } |
203 | 203 | ||
204 | static int mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache, | 204 | static int mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache, |
205 | struct kmem_cache *base_cache, int min, | 205 | struct kmem_cache *base_cache, int min) |
206 | gfp_t gfp_flags) | ||
207 | { | 206 | { |
208 | void *obj; | 207 | void *obj; |
209 | 208 | ||
210 | if (cache->nobjs >= min) | 209 | if (cache->nobjs >= min) |
211 | return 0; | 210 | return 0; |
212 | while (cache->nobjs < ARRAY_SIZE(cache->objects)) { | 211 | while (cache->nobjs < ARRAY_SIZE(cache->objects)) { |
213 | obj = kmem_cache_zalloc(base_cache, gfp_flags); | 212 | obj = kmem_cache_zalloc(base_cache, GFP_KERNEL); |
214 | if (!obj) | 213 | if (!obj) |
215 | return -ENOMEM; | 214 | return -ENOMEM; |
216 | cache->objects[cache->nobjs++] = obj; | 215 | cache->objects[cache->nobjs++] = obj; |
@@ -225,14 +224,14 @@ static void mmu_free_memory_cache(struct kvm_mmu_memory_cache *mc) | |||
225 | } | 224 | } |
226 | 225 | ||
227 | static int mmu_topup_memory_cache_page(struct kvm_mmu_memory_cache *cache, | 226 | static int mmu_topup_memory_cache_page(struct kvm_mmu_memory_cache *cache, |
228 | int min, gfp_t gfp_flags) | 227 | int min) |
229 | { | 228 | { |
230 | struct page *page; | 229 | struct page *page; |
231 | 230 | ||
232 | if (cache->nobjs >= min) | 231 | if (cache->nobjs >= min) |
233 | return 0; | 232 | return 0; |
234 | while (cache->nobjs < ARRAY_SIZE(cache->objects)) { | 233 | while (cache->nobjs < ARRAY_SIZE(cache->objects)) { |
235 | page = alloc_page(gfp_flags); | 234 | page = alloc_page(GFP_KERNEL); |
236 | if (!page) | 235 | if (!page) |
237 | return -ENOMEM; | 236 | return -ENOMEM; |
238 | set_page_private(page, 0); | 237 | set_page_private(page, 0); |
@@ -247,44 +246,28 @@ static void mmu_free_memory_cache_page(struct kvm_mmu_memory_cache *mc) | |||
247 | free_page((unsigned long)mc->objects[--mc->nobjs]); | 246 | free_page((unsigned long)mc->objects[--mc->nobjs]); |
248 | } | 247 | } |
249 | 248 | ||
250 | static int __mmu_topup_memory_caches(struct kvm_vcpu *vcpu, gfp_t gfp_flags) | 249 | static int mmu_topup_memory_caches(struct kvm_vcpu *vcpu) |
251 | { | 250 | { |
252 | int r; | 251 | int r; |
253 | 252 | ||
253 | kvm_mmu_free_some_pages(vcpu); | ||
254 | r = mmu_topup_memory_cache(&vcpu->mmu_pte_chain_cache, | 254 | r = mmu_topup_memory_cache(&vcpu->mmu_pte_chain_cache, |
255 | pte_chain_cache, 4, gfp_flags); | 255 | pte_chain_cache, 4); |
256 | if (r) | 256 | if (r) |
257 | goto out; | 257 | goto out; |
258 | r = mmu_topup_memory_cache(&vcpu->mmu_rmap_desc_cache, | 258 | r = mmu_topup_memory_cache(&vcpu->mmu_rmap_desc_cache, |
259 | rmap_desc_cache, 1, gfp_flags); | 259 | rmap_desc_cache, 1); |
260 | if (r) | 260 | if (r) |
261 | goto out; | 261 | goto out; |
262 | r = mmu_topup_memory_cache_page(&vcpu->mmu_page_cache, 4, gfp_flags); | 262 | r = mmu_topup_memory_cache_page(&vcpu->mmu_page_cache, 4); |
263 | if (r) | 263 | if (r) |
264 | goto out; | 264 | goto out; |
265 | r = mmu_topup_memory_cache(&vcpu->mmu_page_header_cache, | 265 | r = mmu_topup_memory_cache(&vcpu->mmu_page_header_cache, |
266 | mmu_page_header_cache, 4, gfp_flags); | 266 | mmu_page_header_cache, 4); |
267 | out: | 267 | out: |
268 | return r; | 268 | return r; |
269 | } | 269 | } |
270 | 270 | ||
271 | static int mmu_topup_memory_caches(struct kvm_vcpu *vcpu) | ||
272 | { | ||
273 | int r; | ||
274 | |||
275 | r = __mmu_topup_memory_caches(vcpu, GFP_NOWAIT); | ||
276 | kvm_mmu_free_some_pages(vcpu); | ||
277 | if (r < 0) { | ||
278 | spin_unlock(&vcpu->kvm->lock); | ||
279 | kvm_arch_ops->vcpu_put(vcpu); | ||
280 | r = __mmu_topup_memory_caches(vcpu, GFP_KERNEL); | ||
281 | kvm_arch_ops->vcpu_load(vcpu); | ||
282 | spin_lock(&vcpu->kvm->lock); | ||
283 | kvm_mmu_free_some_pages(vcpu); | ||
284 | } | ||
285 | return r; | ||
286 | } | ||
287 | |||
288 | static void mmu_free_memory_caches(struct kvm_vcpu *vcpu) | 271 | static void mmu_free_memory_caches(struct kvm_vcpu *vcpu) |
289 | { | 272 | { |
290 | mmu_free_memory_cache(&vcpu->mmu_pte_chain_cache); | 273 | mmu_free_memory_cache(&vcpu->mmu_pte_chain_cache); |
@@ -969,7 +952,7 @@ static int nonpaging_init_context(struct kvm_vcpu *vcpu) | |||
969 | static void kvm_mmu_flush_tlb(struct kvm_vcpu *vcpu) | 952 | static void kvm_mmu_flush_tlb(struct kvm_vcpu *vcpu) |
970 | { | 953 | { |
971 | ++vcpu->stat.tlb_flush; | 954 | ++vcpu->stat.tlb_flush; |
972 | kvm_arch_ops->tlb_flush(vcpu); | 955 | kvm_x86_ops->tlb_flush(vcpu); |
973 | } | 956 | } |
974 | 957 | ||
975 | static void paging_new_cr3(struct kvm_vcpu *vcpu) | 958 | static void paging_new_cr3(struct kvm_vcpu *vcpu) |
@@ -982,7 +965,7 @@ static void inject_page_fault(struct kvm_vcpu *vcpu, | |||
982 | u64 addr, | 965 | u64 addr, |
983 | u32 err_code) | 966 | u32 err_code) |
984 | { | 967 | { |
985 | kvm_arch_ops->inject_page_fault(vcpu, addr, err_code); | 968 | kvm_x86_ops->inject_page_fault(vcpu, addr, err_code); |
986 | } | 969 | } |
987 | 970 | ||
988 | static void paging_free(struct kvm_vcpu *vcpu) | 971 | static void paging_free(struct kvm_vcpu *vcpu) |
@@ -1071,15 +1054,15 @@ int kvm_mmu_load(struct kvm_vcpu *vcpu) | |||
1071 | { | 1054 | { |
1072 | int r; | 1055 | int r; |
1073 | 1056 | ||
1074 | spin_lock(&vcpu->kvm->lock); | 1057 | mutex_lock(&vcpu->kvm->lock); |
1075 | r = mmu_topup_memory_caches(vcpu); | 1058 | r = mmu_topup_memory_caches(vcpu); |
1076 | if (r) | 1059 | if (r) |
1077 | goto out; | 1060 | goto out; |
1078 | mmu_alloc_roots(vcpu); | 1061 | mmu_alloc_roots(vcpu); |
1079 | kvm_arch_ops->set_cr3(vcpu, vcpu->mmu.root_hpa); | 1062 | kvm_x86_ops->set_cr3(vcpu, vcpu->mmu.root_hpa); |
1080 | kvm_mmu_flush_tlb(vcpu); | 1063 | kvm_mmu_flush_tlb(vcpu); |
1081 | out: | 1064 | out: |
1082 | spin_unlock(&vcpu->kvm->lock); | 1065 | mutex_unlock(&vcpu->kvm->lock); |
1083 | return r; | 1066 | return r; |
1084 | } | 1067 | } |
1085 | EXPORT_SYMBOL_GPL(kvm_mmu_load); | 1068 | EXPORT_SYMBOL_GPL(kvm_mmu_load); |
@@ -1124,7 +1107,7 @@ static void mmu_pte_write_new_pte(struct kvm_vcpu *vcpu, | |||
1124 | } | 1107 | } |
1125 | 1108 | ||
1126 | void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, | 1109 | void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, |
1127 | const u8 *old, const u8 *new, int bytes) | 1110 | const u8 *new, int bytes) |
1128 | { | 1111 | { |
1129 | gfn_t gfn = gpa >> PAGE_SHIFT; | 1112 | gfn_t gfn = gpa >> PAGE_SHIFT; |
1130 | struct kvm_mmu_page *page; | 1113 | struct kvm_mmu_page *page; |