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:
commit
20baa8e515
@ -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;
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user