Skip to content

Commit

Permalink
Merge tag 'kvm-ppc-fixes-5.4-1' of git://git.kernel.org/pub/scm/linux…
Browse files Browse the repository at this point in the history
…/kernel/git/paulus/powerpc into HEAD

PPC KVM fix for 5.4

- Fix a bug in the XIVE code which can cause a host crash.
  • Loading branch information
Paolo Bonzini committed Oct 22, 2019
2 parents 9800c24 + 12ade69 commit 20baa8e
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 10 deletions.
24 changes: 16 additions & 8 deletions arch/powerpc/kvm/book3s_xive.c
Original file line number Diff line number Diff line change
Expand Up @@ -1217,6 +1217,7 @@ int kvmppc_xive_connect_vcpu(struct kvm_device *dev,
struct kvmppc_xive *xive = dev->private;
struct kvmppc_xive_vcpu *xc;
int i, r = -EBUSY;
u32 vp_id;

pr_devel("connect_vcpu(cpu=%d)\n", cpu);

Expand All @@ -1228,25 +1229,32 @@ int kvmppc_xive_connect_vcpu(struct kvm_device *dev,
return -EPERM;
if (vcpu->arch.irq_type != KVMPPC_IRQ_DEFAULT)
return -EBUSY;
if (kvmppc_xive_find_server(vcpu->kvm, cpu)) {
pr_devel("Duplicate !\n");
return -EEXIST;
}
if (cpu >= (KVM_MAX_VCPUS * vcpu->kvm->arch.emul_smt_mode)) {
pr_devel("Out of bounds !\n");
return -EINVAL;
}
xc = kzalloc(sizeof(*xc), GFP_KERNEL);
if (!xc)
return -ENOMEM;

/* We need to synchronize with queue provisioning */
mutex_lock(&xive->lock);

vp_id = kvmppc_xive_vp(xive, cpu);
if (kvmppc_xive_vp_in_use(xive->kvm, vp_id)) {
pr_devel("Duplicate !\n");
r = -EEXIST;
goto bail;
}

xc = kzalloc(sizeof(*xc), GFP_KERNEL);
if (!xc) {
r = -ENOMEM;
goto bail;
}

vcpu->arch.xive_vcpu = xc;
xc->xive = xive;
xc->vcpu = vcpu;
xc->server_num = cpu;
xc->vp_id = kvmppc_xive_vp(xive, cpu);
xc->vp_id = vp_id;
xc->mfrr = 0xff;
xc->valid = true;

Expand Down
12 changes: 12 additions & 0 deletions arch/powerpc/kvm/book3s_xive.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,18 @@ static inline u32 kvmppc_xive_vp(struct kvmppc_xive *xive, u32 server)
return xive->vp_base + kvmppc_pack_vcpu_id(xive->kvm, server);
}

static inline bool kvmppc_xive_vp_in_use(struct kvm *kvm, u32 vp_id)
{
struct kvm_vcpu *vcpu = NULL;
int i;

kvm_for_each_vcpu(i, vcpu, kvm) {
if (vcpu->arch.xive_vcpu && vp_id == vcpu->arch.xive_vcpu->vp_id)
return true;
}
return false;
}

/*
* Mapping between guest priorities and host priorities
* is as follow.
Expand Down
6 changes: 4 additions & 2 deletions arch/powerpc/kvm/book3s_xive_native.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ int kvmppc_xive_native_connect_vcpu(struct kvm_device *dev,
struct kvmppc_xive *xive = dev->private;
struct kvmppc_xive_vcpu *xc = NULL;
int rc;
u32 vp_id;

pr_devel("native_connect_vcpu(server=%d)\n", server_num);

Expand All @@ -124,7 +125,8 @@ int kvmppc_xive_native_connect_vcpu(struct kvm_device *dev,

mutex_lock(&xive->lock);

if (kvmppc_xive_find_server(vcpu->kvm, server_num)) {
vp_id = kvmppc_xive_vp(xive, server_num);
if (kvmppc_xive_vp_in_use(xive->kvm, vp_id)) {
pr_devel("Duplicate !\n");
rc = -EEXIST;
goto bail;
Expand All @@ -141,7 +143,7 @@ int kvmppc_xive_native_connect_vcpu(struct kvm_device *dev,
xc->vcpu = vcpu;
xc->server_num = server_num;

xc->vp_id = kvmppc_xive_vp(xive, server_num);
xc->vp_id = vp_id;
xc->valid = true;
vcpu->arch.irq_type = KVMPPC_IRQ_XIVE;

Expand Down

0 comments on commit 20baa8e

Please sign in to comment.