Commit b68c6646 authored by Cédric Le Goater's avatar Cédric Le Goater Committed by Michael Ellerman
Browse files

KVM: PPC: Book3S HV: XIVE: Add a 'flags' field



Use it to hold platform specific features. P9 DD2 introduced
single-escalation support. P10 will add others.

Signed-off-by: default avatarCédric Le Goater <clg@kaod.org>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20210720134209.256133-2-clg@kaod.org
parent 17df41fe
Loading
Loading
Loading
Loading
+10 −9
Original line number Diff line number Diff line
@@ -363,9 +363,9 @@ static int xive_check_provisioning(struct kvm *kvm, u8 prio)
		if (!vcpu->arch.xive_vcpu)
			continue;
		rc = xive_provision_queue(vcpu, prio);
		if (rc == 0 && !xive->single_escalation)
		if (rc == 0 && !kvmppc_xive_has_single_escalation(xive))
			kvmppc_xive_attach_escalation(vcpu, prio,
						      xive->single_escalation);
						      kvmppc_xive_has_single_escalation(xive));
		if (rc)
			return rc;
	}
@@ -1199,7 +1199,7 @@ void kvmppc_xive_cleanup_vcpu(struct kvm_vcpu *vcpu)
	/* Free escalations */
	for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) {
		if (xc->esc_virq[i]) {
			if (xc->xive->single_escalation)
			if (kvmppc_xive_has_single_escalation(xc->xive))
				xive_cleanup_single_escalation(vcpu, xc,
							xc->esc_virq[i]);
			free_irq(xc->esc_virq[i], vcpu);
@@ -1340,7 +1340,7 @@ int kvmppc_xive_connect_vcpu(struct kvm_device *dev,
	 * Enable the VP first as the single escalation mode will
	 * affect escalation interrupts numbering
	 */
	r = xive_native_enable_vp(xc->vp_id, xive->single_escalation);
	r = xive_native_enable_vp(xc->vp_id, kvmppc_xive_has_single_escalation(xive));
	if (r) {
		pr_err("Failed to enable VP in OPAL, err %d\n", r);
		goto bail;
@@ -1357,15 +1357,15 @@ int kvmppc_xive_connect_vcpu(struct kvm_device *dev,
		struct xive_q *q = &xc->queues[i];

		/* Single escalation, no queue 7 */
		if (i == 7 && xive->single_escalation)
		if (i == 7 && kvmppc_xive_has_single_escalation(xive))
			break;

		/* Is queue already enabled ? Provision it */
		if (xive->qmap & (1 << i)) {
			r = xive_provision_queue(vcpu, i);
			if (r == 0 && !xive->single_escalation)
			if (r == 0 && !kvmppc_xive_has_single_escalation(xive))
				kvmppc_xive_attach_escalation(
					vcpu, i, xive->single_escalation);
					vcpu, i, kvmppc_xive_has_single_escalation(xive));
			if (r)
				goto bail;
		} else {
@@ -1380,7 +1380,7 @@ int kvmppc_xive_connect_vcpu(struct kvm_device *dev,
	}

	/* If not done above, attach priority 0 escalation */
	r = kvmppc_xive_attach_escalation(vcpu, 0, xive->single_escalation);
	r = kvmppc_xive_attach_escalation(vcpu, 0, kvmppc_xive_has_single_escalation(xive));
	if (r)
		goto bail;

@@ -2135,7 +2135,8 @@ static int kvmppc_xive_create(struct kvm_device *dev, u32 type)
	 */
	xive->nr_servers = KVM_MAX_VCPUS;

	xive->single_escalation = xive_native_has_single_escalation();
	if (xive_native_has_single_escalation())
		xive->flags |= KVMPPC_XIVE_FLAG_SINGLE_ESCALATION;

	kvm->arch.xive = xive;
	return 0;
+8 −1
Original line number Diff line number Diff line
@@ -97,6 +97,8 @@ struct kvmppc_xive_ops {
	int (*reset_mapped)(struct kvm *kvm, unsigned long guest_irq);
};

#define KVMPPC_XIVE_FLAG_SINGLE_ESCALATION 0x1

struct kvmppc_xive {
	struct kvm *kvm;
	struct kvm_device *dev;
@@ -133,7 +135,7 @@ struct kvmppc_xive {
	u32	q_page_order;

	/* Flags */
	u8	single_escalation;
	u8	flags;

	/* Number of entries in the VP block */
	u32	nr_servers;
@@ -308,5 +310,10 @@ void xive_cleanup_single_escalation(struct kvm_vcpu *vcpu,
int kvmppc_xive_compute_vp_id(struct kvmppc_xive *xive, u32 cpu, u32 *vp);
int kvmppc_xive_set_nr_servers(struct kvmppc_xive *xive, u64 addr);

static inline bool kvmppc_xive_has_single_escalation(struct kvmppc_xive *xive)
{
	return xive->flags & KVMPPC_XIVE_FLAG_SINGLE_ESCALATION;
}

#endif /* CONFIG_KVM_XICS */
#endif /* _KVM_PPC_BOOK3S_XICS_H */
+7 −5
Original line number Diff line number Diff line
@@ -93,7 +93,7 @@ void kvmppc_xive_native_cleanup_vcpu(struct kvm_vcpu *vcpu)
	for (i = 0; i < KVMPPC_XIVE_Q_COUNT; i++) {
		/* Free the escalation irq */
		if (xc->esc_virq[i]) {
			if (xc->xive->single_escalation)
			if (kvmppc_xive_has_single_escalation(xc->xive))
				xive_cleanup_single_escalation(vcpu, xc,
							xc->esc_virq[i]);
			free_irq(xc->esc_virq[i], vcpu);
@@ -172,7 +172,7 @@ int kvmppc_xive_native_connect_vcpu(struct kvm_device *dev,
	 * Enable the VP first as the single escalation mode will
	 * affect escalation interrupts numbering
	 */
	rc = xive_native_enable_vp(xc->vp_id, xive->single_escalation);
	rc = xive_native_enable_vp(xc->vp_id, kvmppc_xive_has_single_escalation(xive));
	if (rc) {
		pr_err("Failed to enable VP in OPAL: %d\n", rc);
		goto bail;
@@ -693,7 +693,7 @@ static int kvmppc_xive_native_set_queue_config(struct kvmppc_xive *xive,
	}

	rc = kvmppc_xive_attach_escalation(vcpu, priority,
					   xive->single_escalation);
					   kvmppc_xive_has_single_escalation(xive));
error:
	if (rc)
		kvmppc_xive_native_cleanup_queue(vcpu, priority);
@@ -820,7 +820,7 @@ static int kvmppc_xive_reset(struct kvmppc_xive *xive)
		for (prio = 0; prio < KVMPPC_XIVE_Q_COUNT; prio++) {

			/* Single escalation, no queue 7 */
			if (prio == 7 && xive->single_escalation)
			if (prio == 7 && kvmppc_xive_has_single_escalation(xive))
				break;

			if (xc->esc_virq[prio]) {
@@ -1111,7 +1111,9 @@ static int kvmppc_xive_native_create(struct kvm_device *dev, u32 type)
	 */
	xive->nr_servers = KVM_MAX_VCPUS;

	xive->single_escalation = xive_native_has_single_escalation();
	if (xive_native_has_single_escalation())
		xive->flags |= KVMPPC_XIVE_FLAG_SINGLE_ESCALATION;

	xive->ops = &kvmppc_xive_native_ops;

	kvm->arch.xive = xive;