Skip to content

Commit

Permalink
kvm: Make VM ioctl do valloc for some archs
Browse files Browse the repository at this point in the history
The kvm struct has been bloating. For example, it's tens of kilo-bytes
for x86, which turns out to be a large amount of memory to allocate
contiguously via kzalloc. Thus, this patch does the following:
1. Uses architecture-specific routines to allocate the kvm struct via
   vzalloc for x86.
2. Switches arm to __KVM_HAVE_ARCH_VM_ALLOC so that it can use vzalloc
   when has_vhe() is true.

Other architectures continue to default to kalloc, as they have a
dependency on kalloc or have a small-enough struct kvm.

Signed-off-by: Marc Orr <marcorr@google.com>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
  • Loading branch information
Marc Orr authored and Paolo Bonzini committed Jun 1, 2018
1 parent 1499fa8 commit d1e5b0e
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 4 deletions.
4 changes: 4 additions & 0 deletions arch/arm/include/asm/kvm_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -324,4 +324,8 @@ static inline bool kvm_arm_harden_branch_predictor(void)
static inline void kvm_vcpu_load_sysregs(struct kvm_vcpu *vcpu) {}
static inline void kvm_vcpu_put_sysregs(struct kvm_vcpu *vcpu) {}

#define __KVM_HAVE_ARCH_VM_ALLOC
struct kvm *kvm_arch_alloc_vm(void);
void kvm_arch_free_vm(struct kvm *kvm);

#endif /* __ARM_KVM_HOST_H__ */
4 changes: 4 additions & 0 deletions arch/arm64/include/asm/kvm_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -482,4 +482,8 @@ static inline bool kvm_arm_harden_branch_predictor(void)
void kvm_vcpu_load_sysregs(struct kvm_vcpu *vcpu);
void kvm_vcpu_put_sysregs(struct kvm_vcpu *vcpu);

#define __KVM_HAVE_ARCH_VM_ALLOC
struct kvm *kvm_arch_alloc_vm(void);
void kvm_arch_free_vm(struct kvm *kvm);

#endif /* __ARM64_KVM_HOST_H__ */
4 changes: 2 additions & 2 deletions arch/x86/kvm/svm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1852,13 +1852,13 @@ static void __unregister_enc_region_locked(struct kvm *kvm,

static struct kvm *svm_vm_alloc(void)
{
struct kvm_svm *kvm_svm = kzalloc(sizeof(struct kvm_svm), GFP_KERNEL);
struct kvm_svm *kvm_svm = vzalloc(sizeof(struct kvm_svm));
return &kvm_svm->kvm;
}

static void svm_vm_free(struct kvm *kvm)
{
kfree(to_kvm_svm(kvm));
vfree(to_kvm_svm(kvm));
}

static void sev_vm_destroy(struct kvm *kvm)
Expand Down
4 changes: 2 additions & 2 deletions arch/x86/kvm/vmx.c
Original file line number Diff line number Diff line change
Expand Up @@ -10139,13 +10139,13 @@ STACK_FRAME_NON_STANDARD(vmx_vcpu_run);

static struct kvm *vmx_vm_alloc(void)
{
struct kvm_vmx *kvm_vmx = kzalloc(sizeof(struct kvm_vmx), GFP_KERNEL);
struct kvm_vmx *kvm_vmx = vzalloc(sizeof(struct kvm_vmx));
return &kvm_vmx->kvm;
}

static void vmx_vm_free(struct kvm *kvm)
{
kfree(to_kvm_vmx(kvm));
vfree(to_kvm_vmx(kvm));
}

static void vmx_switch_vmcs(struct kvm_vcpu *vcpu, struct loaded_vmcs *vmcs)
Expand Down
5 changes: 5 additions & 0 deletions include/linux/kvm_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <linux/preempt.h>
#include <linux/msi.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/rcupdate.h>
#include <linux/ratelimit.h>
#include <linux/err.h>
Expand Down Expand Up @@ -811,6 +812,10 @@ bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu);
int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu);

#ifndef __KVM_HAVE_ARCH_VM_ALLOC
/*
* All architectures that want to use vzalloc currently also
* need their own kvm_arch_alloc_vm implementation.
*/
static inline struct kvm *kvm_arch_alloc_vm(void)
{
return kzalloc(sizeof(struct kvm), GFP_KERNEL);
Expand Down
15 changes: 15 additions & 0 deletions virt/kvm/arm/arm.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,21 @@ long kvm_arch_dev_ioctl(struct file *filp,
return -EINVAL;
}

struct kvm *kvm_arch_alloc_vm(void)
{
if (!has_vhe())
return kzalloc(sizeof(struct kvm), GFP_KERNEL);

return vzalloc(sizeof(struct kvm));
}

void kvm_arch_free_vm(struct kvm *kvm)
{
if (!has_vhe())
kfree(kvm);
else
vfree(kvm);
}

struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id)
{
Expand Down

0 comments on commit d1e5b0e

Please sign in to comment.