Skip to content

Commit

Permalink
KVM: Add kvm_arch_vcpu_precreate() to handle pre-allocation issues
Browse files Browse the repository at this point in the history
Add a pre-allocation arch hook to handle checks that are currently done
by arch specific code prior to allocating the vCPU object.  This paves
the way for moving the allocation to common KVM code.

Acked-by: Christoffer Dall <[email protected]>
Signed-off-by: Sean Christopherson <[email protected]>
Reviewed-by: Cornelia Huck <[email protected]>
Signed-off-by: Paolo Bonzini <[email protected]>
  • Loading branch information
Sean Christopherson authored and bonzini committed Jan 24, 2020
1 parent fe931f1 commit 897cc38
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 19 deletions.
5 changes: 5 additions & 0 deletions arch/mips/kvm/mips.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,11 @@ static inline void dump_handler(const char *symbol, void *start, void *end)
pr_debug("\tEND(%s)\n", symbol);
}

int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned int id)
{
return 0;
}

struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id)
{
int err, size;
Expand Down
5 changes: 5 additions & 0 deletions arch/powerpc/kvm/powerpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,11 @@ void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
kvmppc_core_flush_memslot(kvm, slot);
}

int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned int id)
{
return 0;
}

struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id)
{
struct kvm_vcpu *vcpu;
Expand Down
12 changes: 8 additions & 4 deletions arch/s390/kvm/kvm-s390.c
Original file line number Diff line number Diff line change
Expand Up @@ -3035,15 +3035,19 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
return rc;
}

int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned int id)
{
if (!kvm_is_ucontrol(kvm) && !sca_can_add_vcpu(kvm, id))
return -EINVAL;
return 0;
}

struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
unsigned int id)
{
struct kvm_vcpu *vcpu;
struct sie_page *sie_page;
int rc = -EINVAL;

if (!kvm_is_ucontrol(kvm) && !sca_can_add_vcpu(kvm, id))
goto out;
int rc;

rc = -ENOMEM;

Expand Down
14 changes: 9 additions & 5 deletions arch/x86/kvm/x86.c
Original file line number Diff line number Diff line change
Expand Up @@ -9170,17 +9170,21 @@ static void fx_init(struct kvm_vcpu *vcpu)
vcpu->arch.cr0 |= X86_CR0_ET;
}

int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned int id)
{
if (kvm_check_tsc_unstable() && atomic_read(&kvm->online_vcpus) != 0)
pr_warn_once("kvm: SMP vm created on host with unstable TSC; "
"guest TSC will not be reliable\n");

return 0;
}

struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
unsigned int id)
{
struct kvm_vcpu *vcpu;
int r;

if (kvm_check_tsc_unstable() && atomic_read(&kvm->online_vcpus) != 0)
printk_once(KERN_WARNING
"kvm: SMP vm created on host with unstable TSC; "
"guest TSC will not be reliable\n");

vcpu = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL_ACCOUNT);
if (!vcpu)
return ERR_PTR(-ENOMEM);
Expand Down
1 change: 1 addition & 0 deletions include/linux/kvm_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -874,6 +874,7 @@ void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu);

void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu);
void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu);
int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned int id);
struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id);
int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu);
void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu);
Expand Down
21 changes: 11 additions & 10 deletions virt/kvm/arm/arm.c
Original file line number Diff line number Diff line change
Expand Up @@ -279,21 +279,22 @@ void kvm_arch_free_vm(struct kvm *kvm)
vfree(kvm);
}

int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned int id)
{
if (irqchip_in_kernel(kvm) && vgic_initialized(kvm))
return -EBUSY;

if (id >= kvm->arch.max_vcpus)
return -EINVAL;

return 0;
}

struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id)
{
int err;
struct kvm_vcpu *vcpu;

if (irqchip_in_kernel(kvm) && vgic_initialized(kvm)) {
err = -EBUSY;
goto out;
}

if (id >= kvm->arch.max_vcpus) {
err = -EINVAL;
goto out;
}

vcpu = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL);
if (!vcpu) {
err = -ENOMEM;
Expand Down
4 changes: 4 additions & 0 deletions virt/kvm/kvm_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2728,6 +2728,10 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, u32 id)
kvm->created_vcpus++;
mutex_unlock(&kvm->lock);

r = kvm_arch_vcpu_precreate(kvm, id);
if (r)
goto vcpu_decrement;

vcpu = kvm_arch_vcpu_create(kvm, id);
if (IS_ERR(vcpu)) {
r = PTR_ERR(vcpu);
Expand Down

0 comments on commit 897cc38

Please sign in to comment.