PPC KVM fix for 5.4

- Fix a bug in the XIVE code which can cause a host crash.
 -----BEGIN PGP SIGNATURE-----
 
 iQEzBAABCgAdFiEEv0VLfXa2m9eKuaRpnZrqdyxjcZ8FAl2pKMUACgkQnZrqdyxj
 cZ8ACwgA2M28tdhcK6XA/TBTnGN77oGdQiMdUt4nFm50fXNCvjeRUSGnHYATuj4s
 kS0DfAUVoBI/gvbMYeQEW1MJ6t2n8zYjT2DANx/2Vy3B7vXzEIOcvd9xlP0LEIxD
 yOJBuZWWxb+bqj3l2MBEdAg6gXHpu71G1IymcsIG0UIdfAFEOAuOcQrrnVdpesuC
 I1d0iY0tPzvED9FzyBY94ECm7VLp8khsoz5aFUpatAyIyzK4Met4gR0B89UoSoE/
 BCMmiC/vGSKvjEmtgq0rkc2qL2RH1x7MgGvEwJMLwvnls7m58CgqXlMQ8YsfTZuN
 Y88SY5Nqnl1pybmApZ6vgijjgszQRw==
 =uUTG
 -----END PGP SIGNATURE-----

Merge tag 'kvm-ppc-fixes-5.4-1' of git://git.kernel.org/pub/scm/linux/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.
This commit is contained in:
Paolo Bonzini 2019-10-22 13:31:35 +02:00
commit 20baa8e515
3 changed files with 32 additions and 10 deletions

View File

@ -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);
@ -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;

View File

@ -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.

View File

@ -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);
@ -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;
@ -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;