Skip to content

Commit 3ed0dc0

Browse files
committed
Merge branch 'kvm-arm64/misc' into kvmarm/next
* kvm-arm64/misc: : Miscellaneous fixes/cleanups for KVM/arm64 : : - Avoid GICv4 vLPI configuration when confronted with user error : : - Only attempt vLPI configuration when the target routing is an MSI : : - Document ordering requirements to avoid aforementioned user error KVM: arm64: Tear down vGIC on failed vCPU creation KVM: arm64: Document ordering requirements for irqbypass KVM: arm64: vgic-v4: Fall back to software irqbypass if LPI not found KVM: arm64: vgic-v4: Only WARN for HW IRQ mismatch when unmapping vLPI KVM: arm64: vgic-v4: Only attempt vLPI mapping for actual MSIs Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
2 parents 80e54e8 + 250f253 commit 3ed0dc0

File tree

3 files changed

+32
-8
lines changed

3 files changed

+32
-8
lines changed

Documentation/virt/kvm/devices/arm-vgic-its.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,8 @@ KVM_DEV_ARM_VGIC_GRP_ITS_REGS
126126
ITS Restore Sequence:
127127
---------------------
128128

129-
The following ordering must be followed when restoring the GIC and the ITS:
129+
The following ordering must be followed when restoring the GIC, ITS, and
130+
KVM_IRQFD assignments:
130131

131132
a) restore all guest memory and create vcpus
132133
b) restore all redistributors
@@ -139,6 +140,8 @@ d) restore the ITS in the following order:
139140
3. Load the ITS table data (KVM_DEV_ARM_ITS_RESTORE_TABLES)
140141
4. Restore GITS_CTLR
141142

143+
e) restore KVM_IRQFD assignments for MSIs
144+
142145
Then vcpus can be started.
143146

144147
ITS Table ABI REV0:

arch/arm64/kvm/arm.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,11 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
466466
if (err)
467467
return err;
468468

469-
return kvm_share_hyp(vcpu, vcpu + 1);
469+
err = kvm_share_hyp(vcpu, vcpu + 1);
470+
if (err)
471+
kvm_vgic_vcpu_destroy(vcpu);
472+
473+
return err;
470474
}
471475

472476
void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
@@ -2714,6 +2718,14 @@ int kvm_arch_irq_bypass_add_producer(struct irq_bypass_consumer *cons,
27142718
{
27152719
struct kvm_kernel_irqfd *irqfd =
27162720
container_of(cons, struct kvm_kernel_irqfd, consumer);
2721+
struct kvm_kernel_irq_routing_entry *irq_entry = &irqfd->irq_entry;
2722+
2723+
/*
2724+
* The only thing we have a chance of directly-injecting is LPIs. Maybe
2725+
* one day...
2726+
*/
2727+
if (irq_entry->type != KVM_IRQ_ROUTING_MSI)
2728+
return 0;
27172729

27182730
return kvm_vgic_v4_set_forwarding(irqfd->kvm, prod->irq,
27192731
&irqfd->irq_entry);
@@ -2723,6 +2735,10 @@ void kvm_arch_irq_bypass_del_producer(struct irq_bypass_consumer *cons,
27232735
{
27242736
struct kvm_kernel_irqfd *irqfd =
27252737
container_of(cons, struct kvm_kernel_irqfd, consumer);
2738+
struct kvm_kernel_irq_routing_entry *irq_entry = &irqfd->irq_entry;
2739+
2740+
if (irq_entry->type != KVM_IRQ_ROUTING_MSI)
2741+
return;
27262742

27272743
kvm_vgic_v4_unset_forwarding(irqfd->kvm, prod->irq,
27282744
&irqfd->irq_entry);

arch/arm64/kvm/vgic/vgic-v4.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ int kvm_vgic_v4_set_forwarding(struct kvm *kvm, int virq,
415415
struct vgic_irq *irq;
416416
struct its_vlpi_map map;
417417
unsigned long flags;
418-
int ret;
418+
int ret = 0;
419419

420420
if (!vgic_supports_direct_msis(kvm))
421421
return 0;
@@ -430,10 +430,15 @@ int kvm_vgic_v4_set_forwarding(struct kvm *kvm, int virq,
430430

431431
mutex_lock(&its->its_lock);
432432

433-
/* Perform the actual DevID/EventID -> LPI translation. */
434-
ret = vgic_its_resolve_lpi(kvm, its, irq_entry->msi.devid,
435-
irq_entry->msi.data, &irq);
436-
if (ret)
433+
/*
434+
* Perform the actual DevID/EventID -> LPI translation.
435+
*
436+
* Silently exit if translation fails as the guest (or userspace!) has
437+
* managed to do something stupid. Emulated LPI injection will still
438+
* work if the guest figures itself out at a later time.
439+
*/
440+
if (vgic_its_resolve_lpi(kvm, its, irq_entry->msi.devid,
441+
irq_entry->msi.data, &irq))
437442
goto out;
438443

439444
/* Silently exit if the vLPI is already mapped */
@@ -512,7 +517,7 @@ int kvm_vgic_v4_unset_forwarding(struct kvm *kvm, int virq,
512517
if (ret)
513518
goto out;
514519

515-
WARN_ON(!(irq->hw && irq->host_irq == virq));
520+
WARN_ON(irq->hw && irq->host_irq != virq);
516521
if (irq->hw) {
517522
atomic_dec(&irq->target_vcpu->arch.vgic_cpu.vgic_v3.its_vpe.vlpi_count);
518523
irq->hw = false;

0 commit comments

Comments
 (0)