Re: [PATCH v3 29/32] KVM: arm64: GICv4.1: Allow SGIs to switch between HW and SW interrupts

From: Zenghui Yu
Date: Wed Jan 15 2020 - 08:50:14 EST


Hi Marc,

On 2020/1/15 21:32, Marc Zyngier wrote:
On 2020-01-15 03:49, Zenghui Yu wrote:
Hi,

On 2020/1/15 10:49, Shaokun Zhang wrote:
Hi Marc, [This is from Nianyao]

On 2019/12/24 19:10, Marc Zyngier wrote:
In order to let a guest buy in the new, active-less SGIs, we
need to be able to switch between the two modes.

Handle this by stopping all guest activity, transfer the state
from one mode to the other, and resume the guest.

Signed-off-by: Marc Zyngier <maz@xxxxxxxxxx>
---

[...]

diff --git a/virt/kvm/arm/vgic/vgic-v4.c b/virt/kvm/arm/vgic/vgic-v4.c
index c2fcde104ea2..063785fd2dc7 100644
--- a/virt/kvm/arm/vgic/vgic-v4.c
+++ b/virt/kvm/arm/vgic/vgic-v4.c
@@ -97,6 +97,102 @@ static irqreturn_t vgic_v4_doorbell_handler(int irq, void *info)
ÂÂÂÂÂ return IRQ_HANDLED;
 }
 +static void vgic_v4_sync_sgi_config(struct its_vpe *vpe, struct vgic_irq *irq)
+{
+ÂÂÂ vpe->sgi_config[irq->intid].enabledÂÂÂ = irq->enabled;
+ÂÂÂ vpe->sgi_config[irq->intid].groupÂÂÂÂ = irq->group;
+ÂÂÂ vpe->sgi_config[irq->intid].priorityÂÂÂ = irq->priority;
+}
+
+static void vgic_v4_enable_vsgis(struct kvm_vcpu *vcpu)
+{
+ÂÂÂ struct its_vpe *vpe = &vcpu->arch.vgic_cpu.vgic_v3.its_vpe;
+ÂÂÂ int i;
+
+ÂÂÂ /*
+ÂÂÂÂ * With GICv4.1, every virtual SGI can be directly injected. So
+ÂÂÂÂ * let's pretend that they are HW interrupts, tied to a host
+ÂÂÂÂ * IRQ. The SGI code will do its magic.
+ÂÂÂÂ */
+ÂÂÂ for (i = 0; i < VGIC_NR_SGIS; i++) {
+ÂÂÂÂÂÂÂ struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, i);
+ÂÂÂÂÂÂÂ struct irq_desc *desc;
+ÂÂÂÂÂÂÂ int ret;
+
+ÂÂÂÂÂÂÂ if (irq->hw) {
+ÂÂÂÂÂÂÂÂÂÂÂ vgic_put_irq(vcpu->kvm, irq);
+ÂÂÂÂÂÂÂÂÂÂÂ continue;
+ÂÂÂÂÂÂÂ }
+
+ÂÂÂÂÂÂÂ irq->hw = true;
+ÂÂÂÂÂÂÂ irq->host_irq = irq_find_mapping(vpe->sgi_domain, i);

I think we need to check whether irq_find_mapping returns 0.

+ÂÂÂÂÂÂÂ vgic_v4_sync_sgi_config(vpe, irq);
+ÂÂÂÂÂÂÂ /*
+ÂÂÂÂÂÂÂÂ * SGIs are initialised as disabled. Enable them if
+ÂÂÂÂÂÂÂÂ * required by the rest of the VGIC init code.
+ÂÂÂÂÂÂÂÂ */
+ÂÂÂÂÂÂÂ desc = irq_to_desc(irq->host_irq);
+ÂÂÂÂÂÂÂ ret = irq_domain_activate_irq(irq_desc_get_irq_data(desc),
+ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ false);

If irq->host_irq is not valid , in irq_domain_activate_irq, it will trigger NULL pointer
dereference in host kernel.
I meet a problem here. When hw support GIC4.1, and host kernel is started with
kvm-arm.vgic_v4_enable=0, starting a virtual machine will trigger NULL pointer
dereference in host.

I think the thing is that we should _not_ try to configure vSGIs at all
if kvm-arm.vgic_v4_enable=0 (which indicates we don't allow use of the
GICv4 of direct injection).

We currently set kvm_vgic_global_state.has_gicv4_1 to true if HW support
GICv4.1, regardless whatever the gicv4_enable is (see patch#23 -
vgic_v3_probe). I think this is what actually needs fixing.

Yes, my point exactly. I've pushed out a potential fix [1], and I'd be
grateful if you could let me know whether that fixes it for you.

I haven't had the appropriate HW yet.. Nianyao or Shaokun can help to
test it tomorrow, I think.


Thanks,

ÂÂÂÂÂÂÂ M.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git/commit/?h=irq/gic-v4.1-devel&id=b82c2ee1d3fef66fb85793965c344260f618219d

Anyway, this looks good to me.


Thanks,
Zenghui