mirror of
https://github.com/torvalds/linux.git
synced 2026-08-06 23:43:54 +02:00
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>
This commit is contained in:
commit
3ed0dc03f6
|
|
@ -126,7 +126,8 @@ KVM_DEV_ARM_VGIC_GRP_ITS_REGS
|
|||
ITS Restore Sequence:
|
||||
---------------------
|
||||
|
||||
The following ordering must be followed when restoring the GIC and the ITS:
|
||||
The following ordering must be followed when restoring the GIC, ITS, and
|
||||
KVM_IRQFD assignments:
|
||||
|
||||
a) restore all guest memory and create vcpus
|
||||
b) restore all redistributors
|
||||
|
|
@ -139,6 +140,8 @@ d) restore the ITS in the following order:
|
|||
3. Load the ITS table data (KVM_DEV_ARM_ITS_RESTORE_TABLES)
|
||||
4. Restore GITS_CTLR
|
||||
|
||||
e) restore KVM_IRQFD assignments for MSIs
|
||||
|
||||
Then vcpus can be started.
|
||||
|
||||
ITS Table ABI REV0:
|
||||
|
|
|
|||
|
|
@ -466,7 +466,11 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
return kvm_share_hyp(vcpu, vcpu + 1);
|
||||
err = kvm_share_hyp(vcpu, vcpu + 1);
|
||||
if (err)
|
||||
kvm_vgic_vcpu_destroy(vcpu);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
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,
|
|||
{
|
||||
struct kvm_kernel_irqfd *irqfd =
|
||||
container_of(cons, struct kvm_kernel_irqfd, consumer);
|
||||
struct kvm_kernel_irq_routing_entry *irq_entry = &irqfd->irq_entry;
|
||||
|
||||
/*
|
||||
* The only thing we have a chance of directly-injecting is LPIs. Maybe
|
||||
* one day...
|
||||
*/
|
||||
if (irq_entry->type != KVM_IRQ_ROUTING_MSI)
|
||||
return 0;
|
||||
|
||||
return kvm_vgic_v4_set_forwarding(irqfd->kvm, prod->irq,
|
||||
&irqfd->irq_entry);
|
||||
|
|
@ -2723,6 +2735,10 @@ void kvm_arch_irq_bypass_del_producer(struct irq_bypass_consumer *cons,
|
|||
{
|
||||
struct kvm_kernel_irqfd *irqfd =
|
||||
container_of(cons, struct kvm_kernel_irqfd, consumer);
|
||||
struct kvm_kernel_irq_routing_entry *irq_entry = &irqfd->irq_entry;
|
||||
|
||||
if (irq_entry->type != KVM_IRQ_ROUTING_MSI)
|
||||
return;
|
||||
|
||||
kvm_vgic_v4_unset_forwarding(irqfd->kvm, prod->irq,
|
||||
&irqfd->irq_entry);
|
||||
|
|
|
|||
|
|
@ -415,7 +415,7 @@ int kvm_vgic_v4_set_forwarding(struct kvm *kvm, int virq,
|
|||
struct vgic_irq *irq;
|
||||
struct its_vlpi_map map;
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
if (!vgic_supports_direct_msis(kvm))
|
||||
return 0;
|
||||
|
|
@ -430,10 +430,15 @@ int kvm_vgic_v4_set_forwarding(struct kvm *kvm, int virq,
|
|||
|
||||
mutex_lock(&its->its_lock);
|
||||
|
||||
/* Perform the actual DevID/EventID -> LPI translation. */
|
||||
ret = vgic_its_resolve_lpi(kvm, its, irq_entry->msi.devid,
|
||||
irq_entry->msi.data, &irq);
|
||||
if (ret)
|
||||
/*
|
||||
* Perform the actual DevID/EventID -> LPI translation.
|
||||
*
|
||||
* Silently exit if translation fails as the guest (or userspace!) has
|
||||
* managed to do something stupid. Emulated LPI injection will still
|
||||
* work if the guest figures itself out at a later time.
|
||||
*/
|
||||
if (vgic_its_resolve_lpi(kvm, its, irq_entry->msi.devid,
|
||||
irq_entry->msi.data, &irq))
|
||||
goto out;
|
||||
|
||||
/* Silently exit if the vLPI is already mapped */
|
||||
|
|
@ -512,7 +517,7 @@ int kvm_vgic_v4_unset_forwarding(struct kvm *kvm, int virq,
|
|||
if (ret)
|
||||
goto out;
|
||||
|
||||
WARN_ON(!(irq->hw && irq->host_irq == virq));
|
||||
WARN_ON(irq->hw && irq->host_irq != virq);
|
||||
if (irq->hw) {
|
||||
atomic_dec(&irq->target_vcpu->arch.vgic_cpu.vgic_v3.its_vpe.vlpi_count);
|
||||
irq->hw = false;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user