Commit efe5ddca authored by Greg Kurz's avatar Greg Kurz Committed by Paul Mackerras
Browse files

KVM: PPC: Book3S HV: XIVE: Allow userspace to set the # of VPs



Add a new attribute to both XIVE and XICS-on-XIVE KVM devices so that
userspace can tell how many interrupt servers it needs. If a VM needs
less than the current default of KVM_MAX_VCPUS (2048), we can allocate
less VPs in OPAL. Combined with a core stride (VSMT) that matches the
number of guest threads per core, this may substantially increases the
number of VMs that can run concurrently with an in-kernel XIVE device.

Since the legacy XIVE KVM device is exposed to userspace through the
XICS KVM API, a new attribute group is added to it for this purpose.
While here, fix the syntax of the existing KVM_DEV_XICS_GRP_SOURCES
in the XICS documentation.

Signed-off-by: default avatarGreg Kurz <groug@kaod.org>
Reviewed-by: default avatarCédric Le Goater <clg@kaod.org>
Signed-off-by: default avatarPaul Mackerras <paulus@ozlabs.org>
parent 062cfab7
Loading
Loading
Loading
Loading
+12 −2
Original line number Diff line number Diff line
@@ -3,9 +3,19 @@ XICS interrupt controller
Device type supported: KVM_DEV_TYPE_XICS

Groups:
  KVM_DEV_XICS_SOURCES
  1. KVM_DEV_XICS_GRP_SOURCES
  Attributes: One per interrupt source, indexed by the source number.

  2. KVM_DEV_XICS_GRP_CTRL
  Attributes:
    2.1 KVM_DEV_XICS_NR_SERVERS (write only)
  The kvm_device_attr.addr points to a __u32 value which is the number of
  interrupt server numbers (ie, highest possible vcpu id plus one).
  Errors:
    -EINVAL: Value greater than KVM_MAX_VCPU_ID.
    -EFAULT: Invalid user pointer for attr->addr.
    -EBUSY:  A vcpu is already connected to the device.

This device emulates the XICS (eXternal Interrupt Controller
Specification) defined in PAPR.  The XICS has a set of interrupt
sources, each identified by a 20-bit source number, and a set of
@@ -38,7 +48,7 @@ least-significant end of the word:

Each source has 64 bits of state that can be read and written using
the KVM_GET_DEVICE_ATTR and KVM_SET_DEVICE_ATTR ioctls, specifying the
KVM_DEV_XICS_SOURCES attribute group, with the attribute number being
KVM_DEV_XICS_GRP_SOURCES attribute group, with the attribute number being
the interrupt source number.  The 64 bit state word has the following
bitfields, starting from the least-significant end of the word:

+8 −0
Original line number Diff line number Diff line
@@ -78,6 +78,14 @@ the legacy interrupt mode, referred as XICS (POWER7/8).
    migrating the VM.
    Errors: none

    1.3 KVM_DEV_XIVE_NR_SERVERS (write only)
    The kvm_device_attr.addr points to a __u32 value which is the number of
    interrupt server numbers (ie, highest possible vcpu id plus one).
    Errors:
      -EINVAL: Value greater than KVM_MAX_VCPU_ID.
      -EFAULT: Invalid user pointer for attr->addr.
      -EBUSY:  A vCPU is already connected to the device.

  2. KVM_DEV_XIVE_GRP_SOURCE (write only)
  Initializes a new source in the XIVE device and mask it.
  Attributes:
+3 −0
Original line number Diff line number Diff line
@@ -667,6 +667,8 @@ struct kvm_ppc_cpu_char {

/* PPC64 eXternal Interrupt Controller Specification */
#define KVM_DEV_XICS_GRP_SOURCES	1	/* 64-bit source attributes */
#define KVM_DEV_XICS_GRP_CTRL		2
#define   KVM_DEV_XICS_NR_SERVERS	1

/* Layout of 64-bit source attribute values */
#define  KVM_XICS_DESTINATION_SHIFT	0
@@ -683,6 +685,7 @@ struct kvm_ppc_cpu_char {
#define KVM_DEV_XIVE_GRP_CTRL		1
#define   KVM_DEV_XIVE_RESET		1
#define   KVM_DEV_XIVE_EQ_SYNC		2
#define   KVM_DEV_XIVE_NR_SERVERS	3
#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 */
+10 −0
Original line number Diff line number Diff line
@@ -1911,6 +1911,11 @@ static int xive_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr)
	switch (attr->group) {
	case KVM_DEV_XICS_GRP_SOURCES:
		return xive_set_source(xive, attr->attr, attr->addr);
	case KVM_DEV_XICS_GRP_CTRL:
		switch (attr->attr) {
		case KVM_DEV_XICS_NR_SERVERS:
			return kvmppc_xive_set_nr_servers(xive, attr->addr);
		}
	}
	return -ENXIO;
}
@@ -1936,6 +1941,11 @@ static int xive_has_attr(struct kvm_device *dev, struct kvm_device_attr *attr)
		    attr->attr < KVMPPC_XICS_NR_IRQS)
			return 0;
		break;
	case KVM_DEV_XICS_GRP_CTRL:
		switch (attr->attr) {
		case KVM_DEV_XICS_NR_SERVERS:
			return 0;
		}
	}
	return -ENXIO;
}
+3 −0
Original line number Diff line number Diff line
@@ -921,6 +921,8 @@ static int kvmppc_xive_native_set_attr(struct kvm_device *dev,
			return kvmppc_xive_reset(xive);
		case KVM_DEV_XIVE_EQ_SYNC:
			return kvmppc_xive_native_eq_sync(xive);
		case KVM_DEV_XIVE_NR_SERVERS:
			return kvmppc_xive_set_nr_servers(xive, attr->addr);
		}
		break;
	case KVM_DEV_XIVE_GRP_SOURCE:
@@ -960,6 +962,7 @@ static int kvmppc_xive_native_has_attr(struct kvm_device *dev,
		switch (attr->attr) {
		case KVM_DEV_XIVE_RESET:
		case KVM_DEV_XIVE_EQ_SYNC:
		case KVM_DEV_XIVE_NR_SERVERS:
			return 0;
		}
		break;