Merge tag 'kallsyms_show_value-fix-v5.9-rc1' of git://git.kernel.org/pub/scm/linux...
[linux-2.6-microblaze.git] / virt / kvm / kvm_main.c
index 0a68c9d..2c2c025 100644 (file)
@@ -340,6 +340,61 @@ void kvm_reload_remote_mmus(struct kvm *kvm)
        kvm_make_all_cpus_request(kvm, KVM_REQ_MMU_RELOAD);
 }
 
+#ifdef KVM_ARCH_NR_OBJS_PER_MEMORY_CACHE
+static inline void *mmu_memory_cache_alloc_obj(struct kvm_mmu_memory_cache *mc,
+                                              gfp_t gfp_flags)
+{
+       gfp_flags |= mc->gfp_zero;
+
+       if (mc->kmem_cache)
+               return kmem_cache_alloc(mc->kmem_cache, gfp_flags);
+       else
+               return (void *)__get_free_page(gfp_flags);
+}
+
+int kvm_mmu_topup_memory_cache(struct kvm_mmu_memory_cache *mc, int min)
+{
+       void *obj;
+
+       if (mc->nobjs >= min)
+               return 0;
+       while (mc->nobjs < ARRAY_SIZE(mc->objects)) {
+               obj = mmu_memory_cache_alloc_obj(mc, GFP_KERNEL_ACCOUNT);
+               if (!obj)
+                       return mc->nobjs >= min ? 0 : -ENOMEM;
+               mc->objects[mc->nobjs++] = obj;
+       }
+       return 0;
+}
+
+int kvm_mmu_memory_cache_nr_free_objects(struct kvm_mmu_memory_cache *mc)
+{
+       return mc->nobjs;
+}
+
+void kvm_mmu_free_memory_cache(struct kvm_mmu_memory_cache *mc)
+{
+       while (mc->nobjs) {
+               if (mc->kmem_cache)
+                       kmem_cache_free(mc->kmem_cache, mc->objects[--mc->nobjs]);
+               else
+                       free_page((unsigned long)mc->objects[--mc->nobjs]);
+       }
+}
+
+void *kvm_mmu_memory_cache_alloc(struct kvm_mmu_memory_cache *mc)
+{
+       void *p;
+
+       if (WARN_ON(!mc->nobjs))
+               p = mmu_memory_cache_alloc_obj(mc, GFP_ATOMIC | __GFP_ACCOUNT);
+       else
+               p = mc->objects[--mc->nobjs];
+       BUG_ON(!p);
+       return p;
+}
+#endif
+
 static void kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id)
 {
        mutex_init(&vcpu->mutex);
@@ -1626,6 +1681,14 @@ bool kvm_is_visible_gfn(struct kvm *kvm, gfn_t gfn)
 }
 EXPORT_SYMBOL_GPL(kvm_is_visible_gfn);
 
+bool kvm_vcpu_is_visible_gfn(struct kvm_vcpu *vcpu, gfn_t gfn)
+{
+       struct kvm_memory_slot *memslot = kvm_vcpu_gfn_to_memslot(vcpu, gfn);
+
+       return kvm_is_visible_memslot(memslot);
+}
+EXPORT_SYMBOL_GPL(kvm_vcpu_is_visible_gfn);
+
 unsigned long kvm_host_page_size(struct kvm_vcpu *vcpu, gfn_t gfn)
 {
        struct vm_area_struct *vma;