KVM: Move x86's MMU memory cache helpers to common KVM code
Move x86's memory cache helpers to common KVM code so that they can be reused by arm64 and MIPS in future patches. Suggested-by: Christoffer Dall <christoffer.dall@arm.com> Reviewed-by: Ben Gardon <bgardon@google.com> Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com> Message-Id: <20200703023545.8771-16-sean.j.christopherson@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Родитель
2aa9c199cf
Коммит
6926f95acc
|
@ -1061,47 +1061,6 @@ static void walk_shadow_page_lockless_end(struct kvm_vcpu *vcpu)
|
|||
local_irq_enable();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static 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;
|
||||
}
|
||||
|
||||
static int kvm_mmu_memory_cache_nr_free_objects(struct kvm_mmu_memory_cache *mc)
|
||||
{
|
||||
return mc->nobjs;
|
||||
}
|
||||
|
||||
static 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]);
|
||||
}
|
||||
}
|
||||
|
||||
static int mmu_topup_memory_caches(struct kvm_vcpu *vcpu, bool maybe_indirect)
|
||||
{
|
||||
int r;
|
||||
|
@ -1133,18 +1092,6 @@ static void mmu_free_memory_caches(struct kvm_vcpu *vcpu)
|
|||
kvm_mmu_free_memory_cache(&vcpu->arch.mmu_page_header_cache);
|
||||
}
|
||||
|
||||
static 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;
|
||||
}
|
||||
|
||||
static struct pte_list_desc *mmu_alloc_pte_list_desc(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return kvm_mmu_memory_cache_alloc(&vcpu->arch.mmu_pte_list_desc_cache);
|
||||
|
|
|
@ -817,6 +817,13 @@ void kvm_vcpu_on_spin(struct kvm_vcpu *vcpu, bool usermode_vcpu_not_eligible);
|
|||
void kvm_flush_remote_tlbs(struct kvm *kvm);
|
||||
void kvm_reload_remote_mmus(struct kvm *kvm);
|
||||
|
||||
#ifdef KVM_ARCH_NR_OBJS_PER_MEMORY_CACHE
|
||||
int kvm_mmu_topup_memory_cache(struct kvm_mmu_memory_cache *mc, int min);
|
||||
int kvm_mmu_memory_cache_nr_free_objects(struct kvm_mmu_memory_cache *mc);
|
||||
void kvm_mmu_free_memory_cache(struct kvm_mmu_memory_cache *mc);
|
||||
void *kvm_mmu_memory_cache_alloc(struct kvm_mmu_memory_cache *mc);
|
||||
#endif
|
||||
|
||||
bool kvm_make_vcpus_request_mask(struct kvm *kvm, unsigned int req,
|
||||
struct kvm_vcpu *except,
|
||||
unsigned long *vcpu_bitmap, cpumask_var_t tmp);
|
||||
|
|
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче