diff options
-rw-r--r-- | drivers/kvm/kvm.h | 3 | ||||
-rw-r--r-- | drivers/kvm/kvm_main.c | 7 | ||||
-rw-r--r-- | drivers/kvm/mmu.c | 39 |
3 files changed, 45 insertions, 4 deletions
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h index fceeb840a255..b9c318a9e334 100644 --- a/drivers/kvm/kvm.h +++ b/drivers/kvm/kvm.h | |||
@@ -433,6 +433,9 @@ extern struct kvm_arch_ops *kvm_arch_ops; | |||
433 | int kvm_init_arch(struct kvm_arch_ops *ops, struct module *module); | 433 | int kvm_init_arch(struct kvm_arch_ops *ops, struct module *module); |
434 | void kvm_exit_arch(void); | 434 | void kvm_exit_arch(void); |
435 | 435 | ||
436 | int kvm_mmu_module_init(void); | ||
437 | void kvm_mmu_module_exit(void); | ||
438 | |||
436 | void kvm_mmu_destroy(struct kvm_vcpu *vcpu); | 439 | void kvm_mmu_destroy(struct kvm_vcpu *vcpu); |
437 | int kvm_mmu_create(struct kvm_vcpu *vcpu); | 440 | int kvm_mmu_create(struct kvm_vcpu *vcpu); |
438 | int kvm_mmu_setup(struct kvm_vcpu *vcpu); | 441 | int kvm_mmu_setup(struct kvm_vcpu *vcpu); |
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index 0b30631585bd..ab4dbd7fa5f8 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c | |||
@@ -3063,6 +3063,10 @@ static __init int kvm_init(void) | |||
3063 | static struct page *bad_page; | 3063 | static struct page *bad_page; |
3064 | int r; | 3064 | int r; |
3065 | 3065 | ||
3066 | r = kvm_mmu_module_init(); | ||
3067 | if (r) | ||
3068 | goto out4; | ||
3069 | |||
3066 | r = register_filesystem(&kvm_fs_type); | 3070 | r = register_filesystem(&kvm_fs_type); |
3067 | if (r) | 3071 | if (r) |
3068 | goto out3; | 3072 | goto out3; |
@@ -3091,6 +3095,8 @@ out: | |||
3091 | out2: | 3095 | out2: |
3092 | unregister_filesystem(&kvm_fs_type); | 3096 | unregister_filesystem(&kvm_fs_type); |
3093 | out3: | 3097 | out3: |
3098 | kvm_mmu_module_exit(); | ||
3099 | out4: | ||
3094 | return r; | 3100 | return r; |
3095 | } | 3101 | } |
3096 | 3102 | ||
@@ -3100,6 +3106,7 @@ static __exit void kvm_exit(void) | |||
3100 | __free_page(pfn_to_page(bad_page_address >> PAGE_SHIFT)); | 3106 | __free_page(pfn_to_page(bad_page_address >> PAGE_SHIFT)); |
3101 | mntput(kvmfs_mnt); | 3107 | mntput(kvmfs_mnt); |
3102 | unregister_filesystem(&kvm_fs_type); | 3108 | unregister_filesystem(&kvm_fs_type); |
3109 | kvm_mmu_module_exit(); | ||
3103 | } | 3110 | } |
3104 | 3111 | ||
3105 | module_init(kvm_init) | 3112 | module_init(kvm_init) |
diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c index 9ff74805c7d1..a368ea8297f3 100644 --- a/drivers/kvm/mmu.c +++ b/drivers/kvm/mmu.c | |||
@@ -159,6 +159,9 @@ struct kvm_rmap_desc { | |||
159 | struct kvm_rmap_desc *more; | 159 | struct kvm_rmap_desc *more; |
160 | }; | 160 | }; |
161 | 161 | ||
162 | static struct kmem_cache *pte_chain_cache; | ||
163 | static struct kmem_cache *rmap_desc_cache; | ||
164 | |||
162 | static int is_write_protection(struct kvm_vcpu *vcpu) | 165 | static int is_write_protection(struct kvm_vcpu *vcpu) |
163 | { | 166 | { |
164 | return vcpu->cr0 & CR0_WP_MASK; | 167 | return vcpu->cr0 & CR0_WP_MASK; |
@@ -196,14 +199,14 @@ static int is_rmap_pte(u64 pte) | |||
196 | } | 199 | } |
197 | 200 | ||
198 | static int mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache, | 201 | static int mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache, |
199 | size_t objsize, int min) | 202 | struct kmem_cache *base_cache, int min) |
200 | { | 203 | { |
201 | void *obj; | 204 | void *obj; |
202 | 205 | ||
203 | if (cache->nobjs >= min) | 206 | if (cache->nobjs >= min) |
204 | return 0; | 207 | return 0; |
205 | while (cache->nobjs < ARRAY_SIZE(cache->objects)) { | 208 | while (cache->nobjs < ARRAY_SIZE(cache->objects)) { |
206 | obj = kzalloc(objsize, GFP_NOWAIT); | 209 | obj = kmem_cache_zalloc(base_cache, GFP_NOWAIT); |
207 | if (!obj) | 210 | if (!obj) |
208 | return -ENOMEM; | 211 | return -ENOMEM; |
209 | cache->objects[cache->nobjs++] = obj; | 212 | cache->objects[cache->nobjs++] = obj; |
@@ -222,11 +225,11 @@ static int mmu_topup_memory_caches(struct kvm_vcpu *vcpu) | |||
222 | int r; | 225 | int r; |
223 | 226 | ||
224 | r = mmu_topup_memory_cache(&vcpu->mmu_pte_chain_cache, | 227 | r = mmu_topup_memory_cache(&vcpu->mmu_pte_chain_cache, |
225 | sizeof(struct kvm_pte_chain), 4); | 228 | pte_chain_cache, 4); |
226 | if (r) | 229 | if (r) |
227 | goto out; | 230 | goto out; |
228 | r = mmu_topup_memory_cache(&vcpu->mmu_rmap_desc_cache, | 231 | r = mmu_topup_memory_cache(&vcpu->mmu_rmap_desc_cache, |
229 | sizeof(struct kvm_rmap_desc), 1); | 232 | rmap_desc_cache, 1); |
230 | out: | 233 | out: |
231 | return r; | 234 | return r; |
232 | } | 235 | } |
@@ -1333,6 +1336,34 @@ void kvm_mmu_zap_all(struct kvm_vcpu *vcpu) | |||
1333 | init_kvm_mmu(vcpu); | 1336 | init_kvm_mmu(vcpu); |
1334 | } | 1337 | } |
1335 | 1338 | ||
1339 | void kvm_mmu_module_exit(void) | ||
1340 | { | ||
1341 | if (pte_chain_cache) | ||
1342 | kmem_cache_destroy(pte_chain_cache); | ||
1343 | if (rmap_desc_cache) | ||
1344 | kmem_cache_destroy(rmap_desc_cache); | ||
1345 | } | ||
1346 | |||
1347 | int kvm_mmu_module_init(void) | ||
1348 | { | ||
1349 | pte_chain_cache = kmem_cache_create("kvm_pte_chain", | ||
1350 | sizeof(struct kvm_pte_chain), | ||
1351 | 0, 0, NULL, NULL); | ||
1352 | if (!pte_chain_cache) | ||
1353 | goto nomem; | ||
1354 | rmap_desc_cache = kmem_cache_create("kvm_rmap_desc", | ||
1355 | sizeof(struct kvm_rmap_desc), | ||
1356 | 0, 0, NULL, NULL); | ||
1357 | if (!rmap_desc_cache) | ||
1358 | goto nomem; | ||
1359 | |||
1360 | return 0; | ||
1361 | |||
1362 | nomem: | ||
1363 | kvm_mmu_module_exit(); | ||
1364 | return -ENOMEM; | ||
1365 | } | ||
1366 | |||
1336 | #ifdef AUDIT | 1367 | #ifdef AUDIT |
1337 | 1368 | ||
1338 | static const char *audit_msg; | 1369 | static const char *audit_msg; |