From: Shenming Lu <hidden> Date: 2021-03-13 08:40:32
Hi,
In GICv4.1, migration has been supported except for (directly-injected)
VLPI. And GICv4.1 Spec explicitly gives a way to get the VLPI's pending
state (which was crucially missing in GICv4.0). So we make VLPI migration
capable on GICv4.1 in this series.
In order to support VLPI migration, we need to save and restore all
required configuration information and pending states of VLPIs. But
in fact, the configuration information of VLPIs has already been saved
(or will be reallocated on the dst host...) in vgic(kvm) migration.
So we only have to migrate the pending states of VLPIs specially.
Below is the related workflow in migration.
On the save path:
In migration completion:
pause all vCPUs
|
call each VM state change handler:
pause other devices (just keep from sending interrupts, and
such as VFIO migration protocol has already realized it [1])
|
flush ITS tables into guest RAM
|
flush RDIST pending tables (also flush VLPI pending states here)
|
...
On the resume path:
load each device's state:
restore ITS tables (include pending tables) from guest RAM
|
for other (PCI) devices (paused), if configured to have VLPIs,
establish the forwarding paths of their VLPIs (and transfer
the pending states from kvm's vgic to VPT here)
We have tested this series in VFIO migration, and found some related
issues in QEMU [2].
Links:
[1] vfio: UAPI for migration interface for device state:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a8a24f3f6e38103b77cf399c38eb54e1219d00d6
[2] vfio: Some fixes and optimizations for VFIO migration:
https://patchwork.ozlabs.org/project/qemu-devel/cover/20210310030233.1133-1-lushenming@huawei.com/
History:
v3 -> v4
- Nit fixes.
- Add a CPU cache invalidation right after unmapping the vPE. (Patch 1)
- Drop the setting of PTZ altogether. (Patch 2)
- Bail out if spot !vgic_initialized(). (in Patch 4)
- Communicate the state change (clear pending_latch) via
vgic_queue_irq_unlock. (in Patch 5)
Thanks a lot for the suggestions from Marc!
v2 -> v3
- Add the vgic initialized check to ensure that the allocation and enabling
of the doorbells have already been done before unmapping the vPEs.
- Check all get_vlpi_state related conditions in save_pending_tables in one place.
- Nit fixes.
v1 -> v2:
- Get the VLPI state from the KVM side.
- Nit fixes.
Thanks,
Shenming
Marc Zyngier (1):
irqchip/gic-v3-its: Add a cache invalidation right after vPE unmapping
Shenming Lu (4):
irqchip/gic-v3-its: Drop the setting of PTZ altogether
KVM: arm64: GICv4.1: Add function to get VLPI state
KVM: arm64: GICv4.1: Try to save VLPI state in save_pending_tables
KVM: arm64: GICv4.1: Give a chance to save VLPI state
Zenghui Yu (1):
KVM: arm64: GICv4.1: Restore VLPI pending state to physical side
.../virt/kvm/devices/arm-vgic-its.rst | 2 +-
arch/arm64/kvm/vgic/vgic-its.c | 6 +-
arch/arm64/kvm/vgic/vgic-v3.c | 66 +++++++++++++++++--
arch/arm64/kvm/vgic/vgic-v4.c | 37 +++++++++++
arch/arm64/kvm/vgic/vgic.h | 1 +
drivers/irqchip/irq-gic-v3-its.c | 21 +++++-
6 files changed, 121 insertions(+), 12 deletions(-)
--
2.19.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Shenming Lu <hidden> Date: 2021-03-13 08:40:32
From: Marc Zyngier <maz@kernel.org>
Since there may be a direct read from the CPU side to the VPT after
unmapping the vPE, we add a cache coherency maintenance at the end
of its_vpe_irq_domain_deactivate() to ensure the validity of the VPT
read later.
Signed-off-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Shenming Lu <redacted>
---
drivers/irqchip/irq-gic-v3-its.c | 9 +++++++++
1 file changed, 9 insertions(+)
From: Shenming Lu <hidden> Date: 2021-03-13 08:40:33
GICv4.1 gives a way to get the VLPI state, which needs to map the
vPE first, and after the state read, we may remap the vPE back while
the VPT is not empty. So we can't assume that the VPT is empty at
the first map. Besides, the optimization of PTZ is probably limited
since the HW should be fairly efficient to parse the empty VPT. Let's
drop the setting of PTZ altogether.
Signed-off-by: Shenming Lu <redacted>
---
drivers/irqchip/irq-gic-v3-its.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
@@ -794,8 +794,16 @@ static struct its_vpe *its_build_vmapp_cmd(struct its_node *its,its_encode_alloc(cmd,alloc);-/* We can only signal PTZ when alloc==1. Why do we have two bits? */-its_encode_ptz(cmd,alloc);+/*+*WecanonlysignalPTZwhenalloc==1.Whydowehavetwobits?+*GICv4.1givesawaytogettheVLPIstate,whichneedsthevPE+*tobeunmappedfirst,andinthiscase,wemayremapthevPE+*backwhiletheVPTisnotempty.Sowecan'tassumethatthe+*VPTisemptyatthefirstmap.Besides,theoptimizationofPTZ+*isprobablylimitedsincetheHWshouldbefairlyefficientto+*parsetheemptyVPT.Let'sdropthesettingofPTZaltogether.+*/+its_encode_ptz(cmd,false);its_encode_vconf_addr(cmd,vconf_addr);its_encode_vmapp_default_db(cmd,desc->its_vmapp_cmd.vpe->vpe_db_lpi);
--
2.19.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Shenming Lu <hidden> Date: 2021-03-13 08:40:33
With GICv4.1 and the vPE unmapped, which indicates the invalidation
of any VPT caches associated with the vPE, we can get the VLPI state
by peeking at the VPT. So we add a function for this.
Signed-off-by: Shenming Lu <redacted>
---
arch/arm64/kvm/vgic/vgic-v4.c | 19 +++++++++++++++++++
arch/arm64/kvm/vgic/vgic.h | 1 +
2 files changed, 20 insertions(+)
From: Shenming Lu <hidden> Date: 2021-03-13 08:40:33
From: Zenghui Yu <yuzenghui@huawei.com>
When setting the forwarding path of a VLPI (switch to the HW mode),
we can also transfer the pending state from irq->pending_latch to
VPT (especially in migration, the pending states of VLPIs are restored
into kvm’s vgic first). And we currently send "INT+VSYNC" to trigger
a VLPI to pending.
Signed-off-by: Zenghui Yu <yuzenghui@huawei.com>
Signed-off-by: Shenming Lu <redacted>
---
arch/arm64/kvm/vgic/vgic-v4.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
@@ -449,6 +449,24 @@ int kvm_vgic_v4_set_forwarding(struct kvm *kvm, int virq,irq->host_irq=virq;atomic_inc(&map.vpe->vlpi_count);+/* Transfer pending state */+if(irq->pending_latch){+unsignedlongflags;++ret=irq_set_irqchip_state(irq->host_irq,+IRQCHIP_STATE_PENDING,+irq->pending_latch);+WARN_RATELIMIT(ret,"IRQ %d",irq->host_irq);++/*+*Clearpending_latchandcommunicatethisstate+*changeviavgic_queue_irq_unlock.+*/+raw_spin_lock_irqsave(&irq->irq_lock,flags);+irq->pending_latch=false;+vgic_queue_irq_unlock(kvm,irq,flags);+}+out:mutex_unlock(&its->its_lock);returnret;
--
2.19.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Marc Zyngier <maz@kernel.org> Date: 2021-03-15 08:31:57
On 2021-03-13 08:38, Shenming Lu wrote:
quoted hunk
From: Zenghui Yu <yuzenghui@huawei.com>
When setting the forwarding path of a VLPI (switch to the HW mode),
we can also transfer the pending state from irq->pending_latch to
VPT (especially in migration, the pending states of VLPIs are restored
into kvm’s vgic first). And we currently send "INT+VSYNC" to trigger
a VLPI to pending.
Signed-off-by: Zenghui Yu <yuzenghui@huawei.com>
Signed-off-by: Shenming Lu <redacted>
---
arch/arm64/kvm/vgic/vgic-v4.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/arch/arm64/kvm/vgic/vgic-v4.c
b/arch/arm64/kvm/vgic/vgic-v4.c
index ac029ba3d337..3b82ab80c2f3 100644
@@ -449,6 +449,24 @@ int kvm_vgic_v4_set_forwarding(struct kvm *kvm,
int virq,
irq->host_irq = virq;
atomic_inc(&map.vpe->vlpi_count);
+ /* Transfer pending state */
+ if (irq->pending_latch) {
+ unsigned long flags;
+
+ ret = irq_set_irqchip_state(irq->host_irq,
+ IRQCHIP_STATE_PENDING,
+ irq->pending_latch);
+ WARN_RATELIMIT(ret, "IRQ %d", irq->host_irq);
+
+ /*
+ * Clear pending_latch and communicate this state
+ * change via vgic_queue_irq_unlock.
+ */
+ raw_spin_lock_irqsave(&irq->irq_lock, flags);
+ irq->pending_latch = false;
+ vgic_queue_irq_unlock(kvm, irq, flags);
+ }
+
out:
mutex_unlock(&its->its_lock);
return ret;
The read side of the pending state isn't locked, but the write side is.
I'd rather you lock the whole sequence for peace of mind.
Thanks,
M.
--
Jazz is not dead. It just smells funny...
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Shenming Lu <hidden> Date: 2021-03-15 09:12:55
On 2021/3/15 16:30, Marc Zyngier wrote:
On 2021-03-13 08:38, Shenming Lu wrote:
quoted
From: Zenghui Yu <yuzenghui@huawei.com>
When setting the forwarding path of a VLPI (switch to the HW mode),
we can also transfer the pending state from irq->pending_latch to
VPT (especially in migration, the pending states of VLPIs are restored
into kvm’s vgic first). And we currently send "INT+VSYNC" to trigger
a VLPI to pending.
Signed-off-by: Zenghui Yu <yuzenghui@huawei.com>
Signed-off-by: Shenming Lu <redacted>
---
arch/arm64/kvm/vgic/vgic-v4.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
From: Marc Zyngier <maz@kernel.org> Date: 2021-03-15 09:21:36
On 2021-03-15 09:11, Shenming Lu wrote:
On 2021/3/15 16:30, Marc Zyngier wrote:
quoted
On 2021-03-13 08:38, Shenming Lu wrote:
quoted
From: Zenghui Yu <yuzenghui@huawei.com>
When setting the forwarding path of a VLPI (switch to the HW mode),
we can also transfer the pending state from irq->pending_latch to
VPT (especially in migration, the pending states of VLPIs are
restored
into kvm’s vgic first). And we currently send "INT+VSYNC" to trigger
a VLPI to pending.
Signed-off-by: Zenghui Yu <yuzenghui@huawei.com>
Signed-off-by: Shenming Lu <redacted>
---
arch/arm64/kvm/vgic/vgic-v4.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/arch/arm64/kvm/vgic/vgic-v4.c
b/arch/arm64/kvm/vgic/vgic-v4.c
index ac029ba3d337..3b82ab80c2f3 100644
@@ -449,6 +449,24 @@ int kvm_vgic_v4_set_forwarding(struct kvm *kvm,
int virq,
irq->host_irq = virq;
atomic_inc(&map.vpe->vlpi_count);
+ /* Transfer pending state */
+ if (irq->pending_latch) {
+ unsigned long flags;
+
+ ret = irq_set_irqchip_state(irq->host_irq,
+ IRQCHIP_STATE_PENDING,
+ irq->pending_latch);
+ WARN_RATELIMIT(ret, "IRQ %d", irq->host_irq);
+
+ /*
+ * Clear pending_latch and communicate this state
+ * change via vgic_queue_irq_unlock.
+ */
+ raw_spin_lock_irqsave(&irq->irq_lock, flags);
+ irq->pending_latch = false;
+ vgic_queue_irq_unlock(kvm, irq, flags);
+ }
+
out:
mutex_unlock(&its->its_lock);
return ret;
The read side of the pending state isn't locked, but the write side
is.
I'd rather you lock the whole sequence for peace of mind.
Did you mean to lock before emitting the mapping request, Or just
before reading
the pending state?
Just before reading the pending state, so that we can't get a concurrent
modification of that state while we make the interrupt pending in the
VPT
and clearing it in the emulation.
Thanks,
M.
--
Jazz is not dead. It just smells funny...
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Shenming Lu <hidden> Date: 2021-03-15 09:26:26
On 2021/3/15 17:20, Marc Zyngier wrote:
On 2021-03-15 09:11, Shenming Lu wrote:
quoted
On 2021/3/15 16:30, Marc Zyngier wrote:
quoted
On 2021-03-13 08:38, Shenming Lu wrote:
quoted
From: Zenghui Yu <yuzenghui@huawei.com>
When setting the forwarding path of a VLPI (switch to the HW mode),
we can also transfer the pending state from irq->pending_latch to
VPT (especially in migration, the pending states of VLPIs are restored
into kvm’s vgic first). And we currently send "INT+VSYNC" to trigger
a VLPI to pending.
Signed-off-by: Zenghui Yu <yuzenghui@huawei.com>
Signed-off-by: Shenming Lu <redacted>
---
arch/arm64/kvm/vgic/vgic-v4.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
@@ -449,6 +449,24 @@ int kvm_vgic_v4_set_forwarding(struct kvm *kvm, int virq,
irq->host_irq = virq;
atomic_inc(&map.vpe->vlpi_count);
+ /* Transfer pending state */
+ if (irq->pending_latch) {
+ unsigned long flags;
+
+ ret = irq_set_irqchip_state(irq->host_irq,
+ IRQCHIP_STATE_PENDING,
+ irq->pending_latch);
+ WARN_RATELIMIT(ret, "IRQ %d", irq->host_irq);
+
+ /*
+ * Clear pending_latch and communicate this state
+ * change via vgic_queue_irq_unlock.
+ */
+ raw_spin_lock_irqsave(&irq->irq_lock, flags);
+ irq->pending_latch = false;
+ vgic_queue_irq_unlock(kvm, irq, flags);
+ }
+
out:
mutex_unlock(&its->its_lock);
return ret;
The read side of the pending state isn't locked, but the write side is.
I'd rather you lock the whole sequence for peace of mind.
Did you mean to lock before emitting the mapping request, Or just before reading
the pending state?
Just before reading the pending state, so that we can't get a concurrent
modification of that state while we make the interrupt pending in the VPT
and clearing it in the emulation.
Get it. I will correct it right now.
Thanks,
Shenming
From: Marc Zyngier <maz@kernel.org> Date: 2021-03-15 09:31:15
On 2021-03-15 09:25, Shenming Lu wrote:
On 2021/3/15 17:20, Marc Zyngier wrote:
quoted
On 2021-03-15 09:11, Shenming Lu wrote:
quoted
On 2021/3/15 16:30, Marc Zyngier wrote:
quoted
On 2021-03-13 08:38, Shenming Lu wrote:
quoted
From: Zenghui Yu <yuzenghui@huawei.com>
When setting the forwarding path of a VLPI (switch to the HW mode),
we can also transfer the pending state from irq->pending_latch to
VPT (especially in migration, the pending states of VLPIs are
restored
into kvm’s vgic first). And we currently send "INT+VSYNC" to
trigger
a VLPI to pending.
Signed-off-by: Zenghui Yu <yuzenghui@huawei.com>
Signed-off-by: Shenming Lu <redacted>
---
arch/arm64/kvm/vgic/vgic-v4.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/arch/arm64/kvm/vgic/vgic-v4.c
b/arch/arm64/kvm/vgic/vgic-v4.c
index ac029ba3d337..3b82ab80c2f3 100644
@@ -449,6 +449,24 @@ int kvm_vgic_v4_set_forwarding(struct kvm
*kvm, int virq,
irq->host_irq = virq;
atomic_inc(&map.vpe->vlpi_count);
+ /* Transfer pending state */
+ if (irq->pending_latch) {
+ unsigned long flags;
+
+ ret = irq_set_irqchip_state(irq->host_irq,
+ IRQCHIP_STATE_PENDING,
+ irq->pending_latch);
+ WARN_RATELIMIT(ret, "IRQ %d", irq->host_irq);
+
+ /*
+ * Clear pending_latch and communicate this state
+ * change via vgic_queue_irq_unlock.
+ */
+ raw_spin_lock_irqsave(&irq->irq_lock, flags);
+ irq->pending_latch = false;
+ vgic_queue_irq_unlock(kvm, irq, flags);
+ }
+
out:
mutex_unlock(&its->its_lock);
return ret;
The read side of the pending state isn't locked, but the write side
is.
I'd rather you lock the whole sequence for peace of mind.
Did you mean to lock before emitting the mapping request, Or just
before reading
the pending state?
Just before reading the pending state, so that we can't get a
concurrent
modification of that state while we make the interrupt pending in the
VPT
and clearing it in the emulation.
Get it. I will correct it right now.
Please hold off sending a new version for a few days. My inbox is
exploding...
Thanks,
M.
--
Jazz is not dead. It just smells funny...
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Shenming Lu <hidden> Date: 2021-03-13 08:40:33
Before GICv4.1, we don't have direct access to the VLPI state. So
we simply let it fail early when encountering any VLPI in saving.
But now we don't have to return -EACCES directly if on GICv4.1. Let’s
change the hard code and give a chance to save the VLPI state (and
preserve the UAPI).
Signed-off-by: Shenming Lu <redacted>
---
Documentation/virt/kvm/devices/arm-vgic-its.rst | 2 +-
arch/arm64/kvm/vgic/vgic-its.c | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
@@ -80,7 +80,7 @@ KVM_DEV_ARM_VGIC_GRP_CTRL -EFAULT Invalid guest ram access -EBUSY One or more VCPUS are running -EACCES The virtual ITS is backed by a physical GICv4 ITS, and the- state is not available+ state is not available without GICv4.1 ======= ========================================================== KVM_DEV_ARM_VGIC_GRP_ITS_REGS
From: Shenming Lu <hidden> Date: 2021-03-13 08:40:33
After pausing all vCPUs and devices capable of interrupting, in order
to save the states of all interrupts, besides flushing the states in
kvm’s vgic, we also try to flush the states of VLPIs in the virtual
pending tables into guest RAM, but we need to have GICv4.1 and safely
unmap the vPEs first.
As for the saving of VSGIs, which needs the vPEs to be mapped and might
conflict with the saving of VLPIs, but since we will map the vPEs back
at the end of save_pending_tables and both savings require the kvm->lock
to be held (thus only happen serially), it will work fine.
Signed-off-by: Shenming Lu <redacted>
---
arch/arm64/kvm/vgic/vgic-v3.c | 66 +++++++++++++++++++++++++++++++----
1 file changed, 60 insertions(+), 6 deletions(-)