From: Greg Kurz <hidden> Date: 2019-09-23 15:46:38
Each vCPU of a VM allocates a XIVE VP in OPAL which is associated with
8 event queue (EQ) descriptors, one for each priority. A POWER9 socket
can handle a maximum of 1M event queues.
The powernv platform allocates NR_CPUS (== 2048) VPs for the hypervisor,
and each XIVE KVM device allocates KVM_MAX_VCPUS (== 2048) VPs. This
means that on a bi-socket system, we can create at most:
(2 * 1M) / (8 * 2048) - 1 == 127 XIVE KVM devices
ie, start at most 127 VMs benefiting from an in-kernel interrupt
controller. Subsequent VMs need to rely on a much slower userspace
emulated XIVE or XICS device in QEMU.
This is problematic as one can legitimately expect to start the same
number of mono-cpu VMs as the number of HW threads available on the
system, eg, 144 on a bi-socket POWER9 Witherspoon.
This series allows QEMU to tell KVM how many interrupt servers are needed,
which is likely less than 2048 with a typical VM, eg. it is only 256 for
32 vCPUs with a guest's core stride of 8 and 1 thread per core.
With this I could run ~500 SMP1 VMs on a Witherspoon system.
Patches 1 to 3 are preliminary fixes (1 and 2 have already been posted
but are provided for convenience).
--
Greg
---
Cédric Le Goater (1):
KVM: PPC: Book3S HV: XIVE: initialize private pointer when VPs are allocated
Greg Kurz (5):
KVM: PPC: Book3S HV: XIVE: Set kvm->arch.xive when VPs are allocated
KVM: PPC: Book3S HV: XIVE: Ensure VP isn't already in use
KVM: PPC: Book3S HV: XIVE: Compute the VP id in a common helper
KVM: PPC: Book3S HV: XIVE: Make VP block size configurable
KVM: PPC: Book3S HV: XIVE: Allow userspace to set the # of VPs
Documentation/virt/kvm/devices/xics.txt | 14 +++
Documentation/virt/kvm/devices/xive.txt | 8 ++
arch/powerpc/include/uapi/asm/kvm.h | 3 +
arch/powerpc/kvm/book3s_xive.c | 145 +++++++++++++++++++++++++------
arch/powerpc/kvm/book3s_xive.h | 17 ++++
arch/powerpc/kvm/book3s_xive_native.c | 49 +++++-----
6 files changed, 179 insertions(+), 57 deletions(-)
From: Greg Kurz <hidden> Date: 2019-09-23 15:48:47
From: Cédric Le Goater <clg@kaod.org>
Do not assign the device private pointer before making sure the XIVE
VPs are allocated in OPAL and test pointer validity when releasing
the device.
Fixes: 5422e95103cf ("KVM: PPC: Book3S HV: XIVE: Replace the 'destroy' method by a 'release' method")
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Greg Kurz <redacted>
---
arch/powerpc/kvm/book3s_xive.c | 13 +++++++++++--
arch/powerpc/kvm/book3s_xive_native.c | 13 +++++++++++--
2 files changed, 22 insertions(+), 4 deletions(-)
From: Paul Mackerras <hidden> Date: 2019-09-24 05:31:16
On Mon, Sep 23, 2019 at 05:43:37PM +0200, Greg Kurz wrote:
From: Cédric Le Goater <clg@kaod.org>
Do not assign the device private pointer before making sure the XIVE
VPs are allocated in OPAL and test pointer validity when releasing
the device.
Fixes: 5422e95103cf ("KVM: PPC: Book3S HV: XIVE: Replace the 'destroy' method by a 'release' method")
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Greg Kurz <redacted>
What happens in the case where the OPAL allocation fails? Does the
host crash, or hang, or leak resources? I presume that users can
trigger the allocation failure just by starting a suitably large
number of guests - is that right? Is there an easier way? I'm trying
to work out whether this is urgently needed in 5.4 and the stable
trees or not.
Paul.
From: Greg Kurz <hidden> Date: 2019-09-24 15:31:45
On Tue, 24 Sep 2019 15:28:55 +1000
Paul Mackerras [off-list ref] wrote:
On Mon, Sep 23, 2019 at 05:43:37PM +0200, Greg Kurz wrote:
quoted
From: Cédric Le Goater <clg@kaod.org>
Do not assign the device private pointer before making sure the XIVE
VPs are allocated in OPAL and test pointer validity when releasing
the device.
Fixes: 5422e95103cf ("KVM: PPC: Book3S HV: XIVE: Replace the 'destroy' method by a 'release' method")
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Signed-off-by: Greg Kurz <redacted>
What happens in the case where the OPAL allocation fails? Does the
host crash, or hang, or leak resources? I presume that users can
trigger the allocation failure just by starting a suitably large
number of guests - is that right? Is there an easier way? I'm trying
to work out whether this is urgently needed in 5.4 and the stable
trees or not.
Wait... I don't quite remember how this patch landed in my tree but when
I look at it again I have the impression it tries to fix something that
cannot happen.
It is indeed easy to trigger the allocation failure, eg. start more than
127 guests on a Witherspoon system. But if this happens, the create
function returns an error and the device isn't created. I don't see how
the release function could hence get called with a "partially initialized"
device.
Please ignore this patch. Unfortunately the rest of the series doesn't
apply cleanly without it... I'll rebase and post a v2.
Sorry for the noise :-\
From: Greg Kurz <hidden> Date: 2019-09-23 15:52:11
If we cannot allocate the XIVE VPs in OPAL, the creation of a XIVE or
XICS-on-XIVE device is aborted as expected, but we leave kvm->arch.xive
set forever since the relase method isn't called in this case. Any
subsequent tentative to create a XIVE or XICS-on-XIVE for this VM will
thus always fail. This is a problem for QEMU since it destroys and
re-creates these devices when the VM is reset: the VM would be
restricted to using the emulated XIVE or XICS forever.
As an alternative to adding rollback, do not assign kvm->arch.xive before
making sure the XIVE VPs are allocated in OPAL.
Fixes: 5422e95103cf ("KVM: PPC: Book3S HV: XIVE: Replace the 'destroy' method by a 'release' method")
Signed-off-by: Greg Kurz <redacted>
---
arch/powerpc/kvm/book3s_xive.c | 11 +++++------
arch/powerpc/kvm/book3s_xive_native.c | 2 +-
2 files changed, 6 insertions(+), 7 deletions(-)
@@ -2006,6 +2006,10 @@ static int kvmppc_xive_create(struct kvm_device *dev, u32 type)pr_devel("Creating xive for partition\n");+/* Already there ? */+if(kvm->arch.xive)+return-EEXIST;+xive=kvmppc_xive_get_device(kvm,type);if(!xive)return-ENOMEM;
@@ -2014,12 +2018,6 @@ static int kvmppc_xive_create(struct kvm_device *dev, u32 type)xive->kvm=kvm;mutex_init(&xive->lock);-/* Already there ? */-if(kvm->arch.xive)-ret=-EEXIST;-else-kvm->arch.xive=xive;-/* We use the default queue size set by the host */xive->q_order=xive_native_default_eq_shift();if(xive->q_order<PAGE_SHIFT)
From: Cédric Le Goater <clg@kaod.org> Date: 2019-09-23 16:31:01
On 23/09/2019 17:43, Greg Kurz wrote:
If we cannot allocate the XIVE VPs in OPAL, the creation of a XIVE or
XICS-on-XIVE device is aborted as expected, but we leave kvm->arch.xive
set forever since the relase method isn't called in this case. Any
release
subsequent tentative to create a XIVE or XICS-on-XIVE for this VM will
thus always fail. This is a problem for QEMU since it destroys and
re-creates these devices when the VM is reset: the VM would be
restricted to using the emulated XIVE or XICS forever.
As an alternative to adding rollback, do not assign kvm->arch.xive before
making sure the XIVE VPs are allocated in OPAL.
Fixes: 5422e95103cf ("KVM: PPC: Book3S HV: XIVE: Replace the 'destroy' method by a 'release' method")
Signed-off-by: Greg Kurz <redacted>
@@ -2006,6 +2006,10 @@ static int kvmppc_xive_create(struct kvm_device *dev, u32 type)pr_devel("Creating xive for partition\n");+/* Already there ? */+if(kvm->arch.xive)+return-EEXIST;+xive=kvmppc_xive_get_device(kvm,type);if(!xive)return-ENOMEM;
@@ -2014,12 +2018,6 @@ static int kvmppc_xive_create(struct kvm_device *dev, u32 type)xive->kvm=kvm;mutex_init(&xive->lock);-/* Already there ? */-if(kvm->arch.xive)-ret=-EEXIST;-else-kvm->arch.xive=xive;-/* We use the default queue size set by the host */xive->q_order=xive_native_default_eq_shift();if(xive->q_order<PAGE_SHIFT)
From: Greg Kurz <hidden> Date: 2019-09-23 15:54:23
We currently prevent userspace to connect a new vCPU if we already have
one with the same vCPU id. This is good but unfortunately not enough,
because VP ids derive from the packed vCPU ids, and kvmppc_pack_vcpu_id()
can return colliding values. For examples, 348 stays unchanged since it
is < KVM_MAX_VCPUS, but it is also the packed value of 2392 when the
guest's core stride is 8. Nothing currently prevents userspace to connect
vCPUs with forged ids, that end up being associated to the same VP. This
confuses the irq layer and likely crashes the kernel:
[96631.670454] genirq: Flags mismatch irq 4161. 00010000 (kvm-1-2392) vs. 00010000 (kvm-1-348)
Check the VP id instead of the vCPU id when a new vCPU is connected.
The allocation of the XIVE CPU structure in kvmppc_xive_connect_vcpu()
is moved after the check to avoid the need for rollback.
Signed-off-by: Greg Kurz <redacted>
---
arch/powerpc/kvm/book3s_xive.c | 24 ++++++++++++++++--------
arch/powerpc/kvm/book3s_xive.h | 12 ++++++++++++
arch/powerpc/kvm/book3s_xive_native.c | 6 ++++--
3 files changed, 32 insertions(+), 10 deletions(-)
@@ -1217,6 +1217,7 @@ int kvmppc_xive_connect_vcpu(struct kvm_device *dev,structkvmppc_xive*xive=dev->private;structkvmppc_xive_vcpu*xc;inti,r=-EBUSY;+u32vp_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;+gotobail;+}++xc=kzalloc(sizeof(*xc),GFP_KERNEL);+if(!xc){+r=-ENOMEM;+gotobail;+}+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;
From: Cédric Le Goater <clg@kaod.org> Date: 2019-09-23 16:11:15
On 23/09/2019 17:43, Greg Kurz wrote:
We currently prevent userspace to connect a new vCPU if we already have
one with the same vCPU id. This is good but unfortunately not enough,
because VP ids derive from the packed vCPU ids, and kvmppc_pack_vcpu_id()
can return colliding values. For examples, 348 stays unchanged since it
is < KVM_MAX_VCPUS, but it is also the packed value of 2392 when the
guest's core stride is 8. Nothing currently prevents userspace to connect
vCPUs with forged ids, that end up being associated to the same VP. This
confuses the irq layer and likely crashes the kernel:
[96631.670454] genirq: Flags mismatch irq 4161. 00010000 (kvm-1-2392) vs. 00010000 (kvm-1-348)
Check the VP id instead of the vCPU id when a new vCPU is connected.
The allocation of the XIVE CPU structure in kvmppc_xive_connect_vcpu()
is moved after the check to avoid the need for rollback.
Signed-off-by: Greg Kurz <redacted>
@@ -1217,6 +1217,7 @@ int kvmppc_xive_connect_vcpu(struct kvm_device *dev,structkvmppc_xive*xive=dev->private;structkvmppc_xive_vcpu*xc;inti,r=-EBUSY;+u32vp_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;+gotobail;+}++xc=kzalloc(sizeof(*xc),GFP_KERNEL);+if(!xc){+r=-ENOMEM;+gotobail;+}+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;
From: Paul Mackerras <hidden> Date: 2019-09-24 06:13:18
On Mon, Sep 23, 2019 at 05:43:48PM +0200, Greg Kurz wrote:
We currently prevent userspace to connect a new vCPU if we already have
one with the same vCPU id. This is good but unfortunately not enough,
because VP ids derive from the packed vCPU ids, and kvmppc_pack_vcpu_id()
can return colliding values. For examples, 348 stays unchanged since it
is < KVM_MAX_VCPUS, but it is also the packed value of 2392 when the
guest's core stride is 8. Nothing currently prevents userspace to connect
vCPUs with forged ids, that end up being associated to the same VP. This
confuses the irq layer and likely crashes the kernel:
[96631.670454] genirq: Flags mismatch irq 4161. 00010000 (kvm-1-2392) vs. 00010000 (kvm-1-348)
Have you seen a host kernel crash? How hard would it be to exploit
this, and would it just be a denial of service, or do you think it
could be used to get a use-after-free in the kernel or something like
that?
Also, does this patch depend on the patch 2 in this series?
Paul.
From: Greg Kurz <hidden> Date: 2019-09-24 19:27:03
On Tue, 24 Sep 2019 15:33:28 +1000
Paul Mackerras [off-list ref] wrote:
On Mon, Sep 23, 2019 at 05:43:48PM +0200, Greg Kurz wrote:
quoted
We currently prevent userspace to connect a new vCPU if we already have
one with the same vCPU id. This is good but unfortunately not enough,
because VP ids derive from the packed vCPU ids, and kvmppc_pack_vcpu_id()
can return colliding values. For examples, 348 stays unchanged since it
is < KVM_MAX_VCPUS, but it is also the packed value of 2392 when the
guest's core stride is 8. Nothing currently prevents userspace to connect
vCPUs with forged ids, that end up being associated to the same VP. This
confuses the irq layer and likely crashes the kernel:
[96631.670454] genirq: Flags mismatch irq 4161. 00010000 (kvm-1-2392) vs. 00010000 (kvm-1-348)
I just had to run a guest (SMT1, stride 8, 300 vCPUs) with a patched QEMU
that turns the valid vCPU id 344 into 348 when calling KVM_CAP_IRQ_XICS.
and would it just be a denial of service, or do you think it
could be used to get a use-after-free in the kernel or something like
that?
This triggers a cascade of errors, the ultimate one being to pass
a NULL pointer to irq_data_get_irq_handler_data() during the
escalation irq cleanup if I get it right.
Also, does this patch depend on the patch 2 in this series?
From: Greg Kurz <hidden> Date: 2019-09-23 15:56:41
Reduce code duplication by consolidating the checking of vCPU ids and VP
ids to a common helper used by both legacy and native XIVE KVM devices.
And explain the magic with a comment.
Signed-off-by: Greg Kurz <redacted>
---
arch/powerpc/kvm/book3s_xive.c | 42 ++++++++++++++++++++++++++-------
arch/powerpc/kvm/book3s_xive.h | 1 +
arch/powerpc/kvm/book3s_xive_native.c | 11 ++-------
3 files changed, 36 insertions(+), 18 deletions(-)
@@ -1211,6 +1211,37 @@ void kvmppc_xive_cleanup_vcpu(struct kvm_vcpu *vcpu)vcpu->arch.xive_vcpu=NULL;}+staticboolkvmppc_xive_vcpu_id_valid(structkvmppc_xive*xive,u32cpu)+{+/* We have a block of KVM_MAX_VCPUS VPs. We just need to check+*rawvCPUidsarebelowtheexpectedlimitforthisguest's+*corestride;kvmppc_pack_vcpu_id()willpackthemdowntoan+*indexthatcanbesafelyusedtocomputeaVPidthatbelongs+*totheVPblock.+*/+returncpu<KVM_MAX_VCPUS*xive->kvm->arch.emul_smt_mode;+}++intkvmppc_xive_compute_vp_id(structkvmppc_xive*xive,u32cpu,u32*vp)+{+u32vp_id;++if(!kvmppc_xive_vcpu_id_valid(xive,cpu)){+pr_devel("Out of bounds !\n");+return-EINVAL;+}++vp_id=kvmppc_xive_vp(xive,cpu);+if(kvmppc_xive_vp_in_use(xive->kvm,vp_id)){+pr_devel("Duplicate !\n");+return-EEXIST;+}++*vp=vp_id;++return0;+}+intkvmppc_xive_connect_vcpu(structkvm_device*dev,structkvm_vcpu*vcpu,u32cpu){
@@ -1229,20 +1260,13 @@ int kvmppc_xive_connect_vcpu(struct kvm_device *dev,return-EPERM;if(vcpu->arch.irq_type!=KVMPPC_IRQ_DEFAULT)return-EBUSY;-if(cpu>=(KVM_MAX_VCPUS*vcpu->kvm->arch.emul_smt_mode)){-pr_devel("Out of bounds !\n");-return-EINVAL;-}/* 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;+r=kvmppc_xive_compute_vp_id(xive,cpu,&vp_id);+if(r)gotobail;-}xc=kzalloc(sizeof(*xc),GFP_KERNEL);if(!xc){
From: Greg Kurz <hidden> Date: 2019-09-23 15:58:49
The XIVE VP is an internal structure which allow the XIVE interrupt
controller to maintain the interrupt context state of vCPUs non
dispatched on HW threads.
When a guest is started, the XIVE KVM device allocates a block of
XIVE VPs in OPAL, enough to accommodate the highest possible vCPU
id KVM_MAX_VCPU_ID (16384) packed down to KVM_MAX_VCPUS (2048).
With a guest's core stride of 8 and a threading mode of 1 (QEMU's
default), a VM must run at least 256 vCPUs to actually need such a
range of VPs.
A POWER9 system has a limited XIVE VP space : 512k and KVM is
currently wasting this HW resource with large VP allocations,
especially since a typical VM likely runs with a lot less vCPUs.
Make the size of the VP block configurable. Add an nr_servers
field to the XIVE structure and a function to set it for this
purpose.
Split VP allocation out of the device create function. Since the
VP block isn't used before the first vCPU connects to the XIVE KVM
device, allocation is now performed by kvmppc_xive_connect_vcpu().
This gives the opportunity to set nr_servers in between:
kvmppc_xive_create() / kvmppc_xive_native_create()
.
.
kvmppc_xive_set_nr_servers()
.
.
kvmppc_xive_connect_vcpu() / kvmppc_xive_native_connect_vcpu()
The connect_vcpu() functions check that the vCPU id is below nr_servers
and if it is the first vCPU they allocate the VP block. This is protected
against a concurrent update of nr_servers by kvmppc_xive_set_nr_servers()
with the xive->lock mutex.
Also, the block is allocated once for the device lifetime: nr_servers
should stay constant otherwise connect_vcpu() could generate a boggus
VP id and likely crash OPAL. It is thus forbidden to update nr_servers
once the block is allocated.
If the VP allocation fail, return ENOSPC which seems more appropriate to
report the depletion of system wide HW resource than ENOMEM or ENXIO.
A VM using a stride of 8 and 1 thread per core with 32 vCPUs would hence
only need 256 VPs instead of 2048. If the stride is set to match the number
of threads per core, this goes further down to 32.
This will be exposed to userspace by a subsequent patch.
Signed-off-by: Greg Kurz <redacted>
---
arch/powerpc/kvm/book3s_xive.c | 59 ++++++++++++++++++++++++++-------
arch/powerpc/kvm/book3s_xive.h | 4 ++
arch/powerpc/kvm/book3s_xive_native.c | 18 +++-------
3 files changed, 56 insertions(+), 25 deletions(-)
@@ -1213,13 +1213,13 @@ void kvmppc_xive_cleanup_vcpu(struct kvm_vcpu *vcpu)staticboolkvmppc_xive_vcpu_id_valid(structkvmppc_xive*xive,u32cpu){-/* We have a block of KVM_MAX_VCPUS VPs. We just need to check+/* We have a block of xive->nr_servers VPs. We just need to check*rawvCPUidsarebelowtheexpectedlimitforthisguest's*corestride;kvmppc_pack_vcpu_id()willpackthemdowntoan*indexthatcanbesafelyusedtocomputeaVPidthatbelongs*totheVPblock.*/-returncpu<KVM_MAX_VCPUS*xive->kvm->arch.emul_smt_mode;+returncpu<xive->nr_servers*xive->kvm->arch.emul_smt_mode;}intkvmppc_xive_compute_vp_id(structkvmppc_xive*xive,u32cpu,u32*vp)
@@ -1858,6 +1866,37 @@ int kvmppc_xive_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level,return0;}+intkvmppc_xive_set_nr_servers(structkvmppc_xive*xive,u64addr)+{+u32__user*ubufp=(u32__user*)addr;+u32nr_servers;+intrc=0;++if(get_user(nr_servers,ubufp))+return-EFAULT;++pr_devel("%s nr_servers=%u\n",__func__,nr_servers);++if(nr_servers>KVM_MAX_VCPUS)+return-EINVAL;++mutex_lock(&xive->lock);+/* The VP block is allocated once and freed when the device is+*released.Betternotallowtochangeitssizesinceitsused+*byconnect_vcputovalidatevCPUidsarevalid(eg,setting+*itbacktoahighervaluecouldallowconnect_vcputocome+*upwithaVPidthatgoesbeyondtheVPblock,whichislikely+*tocauseacrashinOPAL).+*/+if(xive->vp_base!=XIVE_INVALID_VP)+rc=-EBUSY;+else+xive->nr_servers=nr_servers;+mutex_unlock(&xive->lock);++returnrc;+}+staticintxive_set_attr(structkvm_device*dev,structkvm_device_attr*attr){structkvmppc_xive*xive=dev->private;
@@ -2034,7 +2073,6 @@ static int kvmppc_xive_create(struct kvm_device *dev, u32 type){structkvmppc_xive*xive;structkvm*kvm=dev->kvm;-intret=0;pr_devel("Creating xive for partition\n");
@@ -2057,18 +2095,15 @@ static int kvmppc_xive_create(struct kvm_device *dev, u32 type)elsexive->q_page_order=xive->q_order-PAGE_SHIFT;-/* Allocate a bunch of VPs */-xive->vp_base=xive_native_alloc_vp_block(KVM_MAX_VCPUS);-pr_devel("VP_Base=%x\n",xive->vp_base);--if(xive->vp_base==XIVE_INVALID_VP)-ret=-ENOMEM;+/* VP allocation is delayed to the first call to connect_vcpu */+xive->vp_base=XIVE_INVALID_VP;+/* KVM_MAX_VCPUS limits the number of VMs to roughly 64 per sockets+*onaPOWER9system.+*/+xive->nr_servers=KVM_MAX_VCPUS;xive->single_escalation=xive_native_has_single_escalation();-if(ret)-returnret;-dev->private=xive;kvm->arch.xive=xive;return0;
@@ -135,6 +135,9 @@ struct kvmppc_xive {/* Flags */u8single_escalation;+/* Number of entries in the VP block */+u32nr_servers;+structkvmppc_xive_ops*ops;structaddress_space*mapping;structmutexmapping_lock;
@@ -1085,23 +1084,16 @@ static int kvmppc_xive_native_create(struct kvm_device *dev, u32 type)mutex_init(&xive->mapping_lock);mutex_init(&xive->lock);-/*-*AllocateabunchofVPs.KVM_MAX_VCPUSisalargevaluefor-*adefault.GettingthemaxnumberofCPUstheVMwas-*configuredwithwouldimproveourusageoftheXIVEVPspace.+/* VP allocation is delayed to the first call to connect_vcpu */+xive->vp_base=XIVE_INVALID_VP;+/* KVM_MAX_VCPUS limits the number of VMs to roughly 64 per sockets+*onaPOWER9system.*/-xive->vp_base=xive_native_alloc_vp_block(KVM_MAX_VCPUS);-pr_devel("VP_Base=%x\n",xive->vp_base);--if(xive->vp_base==XIVE_INVALID_VP)-ret=-ENXIO;+xive->nr_servers=KVM_MAX_VCPUS;xive->single_escalation=xive_native_has_single_escalation();xive->ops=&kvmppc_xive_native_ops;-if(ret)-returnret;-dev->private=xive;kvm->arch.xive=xive;return0;
From: Greg Kurz <hidden> Date: 2019-09-25 08:49:40
On Mon, 23 Sep 2019 17:44:00 +0200
Greg Kurz [off-list ref] wrote:
quoted hunk
The XIVE VP is an internal structure which allow the XIVE interrupt
controller to maintain the interrupt context state of vCPUs non
dispatched on HW threads.
When a guest is started, the XIVE KVM device allocates a block of
XIVE VPs in OPAL, enough to accommodate the highest possible vCPU
id KVM_MAX_VCPU_ID (16384) packed down to KVM_MAX_VCPUS (2048).
With a guest's core stride of 8 and a threading mode of 1 (QEMU's
default), a VM must run at least 256 vCPUs to actually need such a
range of VPs.
A POWER9 system has a limited XIVE VP space : 512k and KVM is
currently wasting this HW resource with large VP allocations,
especially since a typical VM likely runs with a lot less vCPUs.
Make the size of the VP block configurable. Add an nr_servers
field to the XIVE structure and a function to set it for this
purpose.
Split VP allocation out of the device create function. Since the
VP block isn't used before the first vCPU connects to the XIVE KVM
device, allocation is now performed by kvmppc_xive_connect_vcpu().
This gives the opportunity to set nr_servers in between:
kvmppc_xive_create() / kvmppc_xive_native_create()
.
.
kvmppc_xive_set_nr_servers()
.
.
kvmppc_xive_connect_vcpu() / kvmppc_xive_native_connect_vcpu()
The connect_vcpu() functions check that the vCPU id is below nr_servers
and if it is the first vCPU they allocate the VP block. This is protected
against a concurrent update of nr_servers by kvmppc_xive_set_nr_servers()
with the xive->lock mutex.
Also, the block is allocated once for the device lifetime: nr_servers
should stay constant otherwise connect_vcpu() could generate a boggus
VP id and likely crash OPAL. It is thus forbidden to update nr_servers
once the block is allocated.
If the VP allocation fail, return ENOSPC which seems more appropriate to
report the depletion of system wide HW resource than ENOMEM or ENXIO.
A VM using a stride of 8 and 1 thread per core with 32 vCPUs would hence
only need 256 VPs instead of 2048. If the stride is set to match the number
of threads per core, this goes further down to 32.
This will be exposed to userspace by a subsequent patch.
Signed-off-by: Greg Kurz <redacted>
---
arch/powerpc/kvm/book3s_xive.c | 59 ++++++++++++++++++++++++++-------
arch/powerpc/kvm/book3s_xive.h | 4 ++
arch/powerpc/kvm/book3s_xive_native.c | 18 +++-------
3 files changed, 56 insertions(+), 25 deletions(-)
@@ -1213,13 +1213,13 @@ void kvmppc_xive_cleanup_vcpu(struct kvm_vcpu *vcpu)staticboolkvmppc_xive_vcpu_id_valid(structkvmppc_xive*xive,u32cpu){-/* We have a block of KVM_MAX_VCPUS VPs. We just need to check+/* We have a block of xive->nr_servers VPs. We just need to check*rawvCPUidsarebelowtheexpectedlimitforthisguest's*corestride;kvmppc_pack_vcpu_id()willpackthemdowntoan*indexthatcanbesafelyusedtocomputeaVPidthatbelongs*totheVPblock.*/-returncpu<KVM_MAX_VCPUS*xive->kvm->arch.emul_smt_mode;+returncpu<xive->nr_servers*xive->kvm->arch.emul_smt_mode;}intkvmppc_xive_compute_vp_id(structkvmppc_xive*xive,u32cpu,u32*vp)
@@ -1858,6 +1866,37 @@ int kvmppc_xive_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level,return0;}+intkvmppc_xive_set_nr_servers(structkvmppc_xive*xive,u64addr)+{+u32__user*ubufp=(u32__user*)addr;+u32nr_servers;+intrc=0;++if(get_user(nr_servers,ubufp))+return-EFAULT;++pr_devel("%s nr_servers=%u\n",__func__,nr_servers);++if(nr_servers>KVM_MAX_VCPUS)
Drat, this is wrong since QEMU can generate higher vCPU ids (which
is why we need to pack them in the first place). We should check
against KVM_MAX_VCPU_ID here...
+ return -EINVAL;
+
+ mutex_lock(&xive->lock);
+ /* The VP block is allocated once and freed when the device is
+ * released. Better not allow to change its size since its used
+ * by connect_vcpu to validate vCPU ids are valid (eg, setting
+ * it back to a higher value could allow connect_vcpu to come
+ * up with a VP id that goes beyond the VP block, which is likely
+ * to cause a crash in OPAL).
+ */
+ if (xive->vp_base != XIVE_INVALID_VP)
+ rc = -EBUSY;
+ else
+ xive->nr_servers = nr_servers;
... and clip down to KVM_MAX_VCPUS here.
I'll fix this in v2.
@@ -2034,7 +2073,6 @@ static int kvmppc_xive_create(struct kvm_device *dev, u32 type) { struct kvmppc_xive *xive; struct kvm *kvm = dev->kvm;- int ret = 0; pr_devel("Creating xive for partition\n");
@@ -2057,18 +2095,15 @@ static int kvmppc_xive_create(struct kvm_device *dev, u32 type) else xive->q_page_order = xive->q_order - PAGE_SHIFT;- /* Allocate a bunch of VPs */- xive->vp_base = xive_native_alloc_vp_block(KVM_MAX_VCPUS);- pr_devel("VP_Base=%x\n", xive->vp_base);-- if (xive->vp_base == XIVE_INVALID_VP)- ret = -ENOMEM;+ /* VP allocation is delayed to the first call to connect_vcpu */+ xive->vp_base = XIVE_INVALID_VP;+ /* KVM_MAX_VCPUS limits the number of VMs to roughly 64 per sockets+ * on a POWER9 system.+ */+ xive->nr_servers = KVM_MAX_VCPUS; xive->single_escalation = xive_native_has_single_escalation();- if (ret)- return ret;- dev->private = xive; kvm->arch.xive = xive; return 0;
@@ -135,6 +135,9 @@ struct kvmppc_xive {/* Flags */u8single_escalation;+/* Number of entries in the VP block */+u32nr_servers;+structkvmppc_xive_ops*ops;structaddress_space*mapping;structmutexmapping_lock;
@@ -1085,23 +1084,16 @@ static int kvmppc_xive_native_create(struct kvm_device *dev, u32 type)mutex_init(&xive->mapping_lock);mutex_init(&xive->lock);-/*-*AllocateabunchofVPs.KVM_MAX_VCPUSisalargevaluefor-*adefault.GettingthemaxnumberofCPUstheVMwas-*configuredwithwouldimproveourusageoftheXIVEVPspace.+/* VP allocation is delayed to the first call to connect_vcpu */+xive->vp_base=XIVE_INVALID_VP;+/* KVM_MAX_VCPUS limits the number of VMs to roughly 64 per sockets+*onaPOWER9system.*/-xive->vp_base=xive_native_alloc_vp_block(KVM_MAX_VCPUS);-pr_devel("VP_Base=%x\n",xive->vp_base);--if(xive->vp_base==XIVE_INVALID_VP)-ret=-ENXIO;+xive->nr_servers=KVM_MAX_VCPUS;xive->single_escalation=xive_native_has_single_escalation();xive->ops=&kvmppc_xive_native_ops;-if(ret)-returnret;-dev->private=xive;kvm->arch.xive=xive;return0;
From: Greg Kurz <hidden> Date: 2019-09-23 16:01:39
Add a new attribute to both legacy and native XIVE KVM devices so that
userspace can require less interrupt servers than the current default
(KVM_MAX_VCPUS, 2048). This will allow to allocate less VPs in OPAL,
and likely increase the number of VMs that can run with an in-kernel
XIVE implementation.
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: Greg Kurz <redacted>
---
Documentation/virt/kvm/devices/xics.txt | 14 ++++++++++++--
Documentation/virt/kvm/devices/xive.txt | 8 ++++++++
arch/powerpc/include/uapi/asm/kvm.h | 3 +++
arch/powerpc/kvm/book3s_xive.c | 10 ++++++++++
arch/powerpc/kvm/book3s_xive_native.c | 3 +++
5 files changed, 36 insertions(+), 2 deletions(-)
@@ -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_VCPUS.+ -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:
@@ -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_KVM_VCPUS.+ -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:
From: Cédric Le Goater <clg@kaod.org> Date: 2019-09-23 16:05:54
On 23/09/2019 17:44, Greg Kurz wrote:
Add a new attribute to both legacy and native XIVE KVM devices so that
userspace can require less interrupt servers than the current default
(KVM_MAX_VCPUS, 2048). This will allow to allocate less VPs in OPAL,
and likely increase the number of VMs that can run with an in-kernel
XIVE implementation.
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: Greg Kurz <redacted>
@@ -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_VCPUS.+ -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:
@@ -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_KVM_VCPUS.+ -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: