Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7b46b616 authored by Cédric Le Goater's avatar Cédric Le Goater Committed by Paul Mackerras
Browse files

KVM: PPC: Book3S HV: XIVE: Add a control to sync the sources



This control will be used by the H_INT_SYNC hcall from QEMU to flush
event notifications on the XIVE IC owning the source.

Signed-off-by: default avatarCédric Le Goater <clg@kaod.org>
Reviewed-by: default avatarDavid Gibson <david@gibson.dropbear.id.au>
Signed-off-by: default avatarPaul Mackerras <paulus@ozlabs.org>
parent 5ca80647
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -92,3 +92,11 @@ the legacy interrupt mode, referred as XICS (POWER7/8).
    -EINVAL: Invalid queue address
    -EFAULT: Invalid user pointer for attr->addr.
    -EIO:    Configuration of the underlying HW failed

  5. KVM_DEV_XIVE_GRP_SOURCE_SYNC (write only)
  Synchronize the source to flush event notifications
  Attributes:
    Interrupt source number  (64-bit)
  Errors:
    -ENOENT: Unknown source number
    -EINVAL: Not initialized source number
+1 −0
Original line number Diff line number Diff line
@@ -683,6 +683,7 @@ struct kvm_ppc_cpu_char {
#define KVM_DEV_XIVE_GRP_SOURCE		2	/* 64-bit source identifier */
#define KVM_DEV_XIVE_GRP_SOURCE_CONFIG	3	/* 64-bit source identifier */
#define KVM_DEV_XIVE_GRP_EQ_CONFIG	4	/* 64-bit EQ identifier */
#define KVM_DEV_XIVE_GRP_SOURCE_SYNC	5       /* 64-bit source identifier */

/* Layout of 64-bit XIVE source attribute values */
#define KVM_XIVE_LEVEL_SENSITIVE	(1ULL << 0)
+36 −0
Original line number Diff line number Diff line
@@ -335,6 +335,38 @@ static int kvmppc_xive_native_set_source_config(struct kvmppc_xive *xive,
						       priority, masked, eisn);
}

static int kvmppc_xive_native_sync_source(struct kvmppc_xive *xive,
					  long irq, u64 addr)
{
	struct kvmppc_xive_src_block *sb;
	struct kvmppc_xive_irq_state *state;
	struct xive_irq_data *xd;
	u32 hw_num;
	u16 src;
	int rc = 0;

	pr_devel("%s irq=0x%lx", __func__, irq);

	sb = kvmppc_xive_find_source(xive, irq, &src);
	if (!sb)
		return -ENOENT;

	state = &sb->irq_state[src];

	rc = -EINVAL;

	arch_spin_lock(&sb->lock);

	if (state->valid) {
		kvmppc_xive_select_irq(state, &hw_num, &xd);
		xive_native_sync_source(hw_num);
		rc = 0;
	}

	arch_spin_unlock(&sb->lock);
	return rc;
}

static int xive_native_validate_queue_size(u32 qshift)
{
	/*
@@ -670,6 +702,9 @@ static int kvmppc_xive_native_set_attr(struct kvm_device *dev,
	case KVM_DEV_XIVE_GRP_EQ_CONFIG:
		return kvmppc_xive_native_set_queue_config(xive, attr->attr,
							   attr->addr);
	case KVM_DEV_XIVE_GRP_SOURCE_SYNC:
		return kvmppc_xive_native_sync_source(xive, attr->attr,
						      attr->addr);
	}
	return -ENXIO;
}
@@ -699,6 +734,7 @@ static int kvmppc_xive_native_has_attr(struct kvm_device *dev,
		break;
	case KVM_DEV_XIVE_GRP_SOURCE:
	case KVM_DEV_XIVE_GRP_SOURCE_CONFIG:
	case KVM_DEV_XIVE_GRP_SOURCE_SYNC:
		if (attr->attr >= KVMPPC_XIVE_FIRST_IRQ &&
		    attr->attr < KVMPPC_XIVE_NR_IRQS)
			return 0;