aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/mmu.c
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2007-01-05 19:36:54 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2007-01-06 02:55:27 -0500
commite2dec939db126989808853d218e426daaeebc9e2 (patch)
tree5c742e609e43090df396fc1c7a6b4c526099dbea /drivers/kvm/mmu.c
parent714b93da1a6d97307dfafb9915517879d8a66c0d (diff)
[PATCH] KVM: MMU: Detect oom conditions and propagate error to userspace
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/mmu.c')
-rw-r--r--drivers/kvm/mmu.c32
1 files changed, 21 insertions, 11 deletions
diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c
index e96362aa7947..7761089ef3bc 100644
--- a/drivers/kvm/mmu.c
+++ b/drivers/kvm/mmu.c
@@ -166,19 +166,20 @@ static int is_rmap_pte(u64 pte)
166 == (PT_WRITABLE_MASK | PT_PRESENT_MASK); 166 == (PT_WRITABLE_MASK | PT_PRESENT_MASK);
167} 167}
168 168
169static void mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache, 169static int mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache,
170 size_t objsize, int min) 170 size_t objsize, int min)
171{ 171{
172 void *obj; 172 void *obj;
173 173
174 if (cache->nobjs >= min) 174 if (cache->nobjs >= min)
175 return; 175 return 0;
176 while (cache->nobjs < ARRAY_SIZE(cache->objects)) { 176 while (cache->nobjs < ARRAY_SIZE(cache->objects)) {
177 obj = kzalloc(objsize, GFP_NOWAIT); 177 obj = kzalloc(objsize, GFP_NOWAIT);
178 if (!obj) 178 if (!obj)
179 BUG(); 179 return -ENOMEM;
180 cache->objects[cache->nobjs++] = obj; 180 cache->objects[cache->nobjs++] = obj;
181 } 181 }
182 return 0;
182} 183}
183 184
184static void mmu_free_memory_cache(struct kvm_mmu_memory_cache *mc) 185static void mmu_free_memory_cache(struct kvm_mmu_memory_cache *mc)
@@ -187,12 +188,18 @@ static void mmu_free_memory_cache(struct kvm_mmu_memory_cache *mc)
187 kfree(mc->objects[--mc->nobjs]); 188 kfree(mc->objects[--mc->nobjs]);
188} 189}
189 190
190static void mmu_topup_memory_caches(struct kvm_vcpu *vcpu) 191static int mmu_topup_memory_caches(struct kvm_vcpu *vcpu)
191{ 192{
192 mmu_topup_memory_cache(&vcpu->mmu_pte_chain_cache, 193 int r;
193 sizeof(struct kvm_pte_chain), 4); 194
194 mmu_topup_memory_cache(&vcpu->mmu_rmap_desc_cache, 195 r = mmu_topup_memory_cache(&vcpu->mmu_pte_chain_cache,
195 sizeof(struct kvm_rmap_desc), 1); 196 sizeof(struct kvm_pte_chain), 4);
197 if (r)
198 goto out;
199 r = mmu_topup_memory_cache(&vcpu->mmu_rmap_desc_cache,
200 sizeof(struct kvm_rmap_desc), 1);
201out:
202 return r;
196} 203}
197 204
198static void mmu_free_memory_caches(struct kvm_vcpu *vcpu) 205static void mmu_free_memory_caches(struct kvm_vcpu *vcpu)
@@ -824,8 +831,11 @@ static int nonpaging_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
824{ 831{
825 gpa_t addr = gva; 832 gpa_t addr = gva;
826 hpa_t paddr; 833 hpa_t paddr;
834 int r;
827 835
828 mmu_topup_memory_caches(vcpu); 836 r = mmu_topup_memory_caches(vcpu);
837 if (r)
838 return r;
829 839
830 ASSERT(vcpu); 840 ASSERT(vcpu);
831 ASSERT(VALID_PAGE(vcpu->mmu.root_hpa)); 841 ASSERT(VALID_PAGE(vcpu->mmu.root_hpa));
@@ -1052,7 +1062,7 @@ int kvm_mmu_reset_context(struct kvm_vcpu *vcpu)
1052 r = init_kvm_mmu(vcpu); 1062 r = init_kvm_mmu(vcpu);
1053 if (r < 0) 1063 if (r < 0)
1054 goto out; 1064 goto out;
1055 mmu_topup_memory_caches(vcpu); 1065 r = mmu_topup_memory_caches(vcpu);
1056out: 1066out:
1057 return r; 1067 return r;
1058} 1068}