Commit 20baa8e5 authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

Merge tag 'kvm-ppc-fixes-5.4-1' of...

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.
parents 9800c24e 12ade69c
Loading
Loading
Loading
Loading
+16 −8
Original line number Diff line number Diff line
@@ -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;

+12 −0
Original line number Diff line number Diff line
@@ -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.
+4 −2
Original line number Diff line number Diff line
@@ -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;