Skip to content

Commit a8a8dcb

Browse files
committed
Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
Pull arm64 kvm fixes from Catalin Marinas: - Don't drop references on LPIs that weren't visited by the vgic-debug iterator - Cure lock ordering issue when unregistering vgic redistributors - Fix for misaligned stage-2 mappings when VMs are backed by hugetlb pages - Treat SGI registers as UNDEFINED if a VM hasn't been configured for GICv3 * tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: KVM: arm64: Make ICC_*SGI*_EL1 undef in the absence of a vGICv3 KVM: arm64: Ensure canonical IPA is hugepage-aligned when handling fault KVM: arm64: vgic: Don't hold config_lock while unregistering redistributors KVM: arm64: vgic-debug: Don't put unmarked LPIs
2 parents 60f0560 + 75c8f38 commit a8a8dcb

File tree

6 files changed

+33
-5
lines changed

6 files changed

+33
-5
lines changed

arch/arm64/kvm/mmu.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1540,8 +1540,15 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
15401540
vma_pagesize = min(vma_pagesize, (long)max_map_size);
15411541
}
15421542

1543-
if (vma_pagesize == PMD_SIZE || vma_pagesize == PUD_SIZE)
1543+
/*
1544+
* Both the canonical IPA and fault IPA must be hugepage-aligned to
1545+
* ensure we find the right PFN and lay down the mapping in the right
1546+
* place.
1547+
*/
1548+
if (vma_pagesize == PMD_SIZE || vma_pagesize == PUD_SIZE) {
15441549
fault_ipa &= ~(vma_pagesize - 1);
1550+
ipa &= ~(vma_pagesize - 1);
1551+
}
15451552

15461553
gfn = ipa >> PAGE_SHIFT;
15471554
mte_allowed = kvm_vma_mte_allowed(vma);

arch/arm64/kvm/sys_regs.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include <trace/events/kvm.h>
3434

3535
#include "sys_regs.h"
36+
#include "vgic/vgic.h"
3637

3738
#include "trace.h"
3839

@@ -435,6 +436,11 @@ static bool access_gic_sgi(struct kvm_vcpu *vcpu,
435436
{
436437
bool g1;
437438

439+
if (!kvm_has_gicv3(vcpu->kvm)) {
440+
kvm_inject_undefined(vcpu);
441+
return false;
442+
}
443+
438444
if (!p->is_write)
439445
return read_from_write_only(vcpu, p, r);
440446

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ static void iter_unmark_lpis(struct kvm *kvm)
8585
struct vgic_irq *irq;
8686
unsigned long intid;
8787

88-
xa_for_each(&dist->lpi_xa, intid, irq) {
88+
xa_for_each_marked(&dist->lpi_xa, intid, irq, LPI_XA_MARK_DEBUG_ITER) {
8989
xa_clear_mark(&dist->lpi_xa, intid, LPI_XA_MARK_DEBUG_ITER);
9090
vgic_put_irq(kvm, irq);
9191
}

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -417,10 +417,8 @@ static void __kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
417417
kfree(vgic_cpu->private_irqs);
418418
vgic_cpu->private_irqs = NULL;
419419

420-
if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) {
421-
vgic_unregister_redist_iodev(vcpu);
420+
if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3)
422421
vgic_cpu->rd_iodev.base_addr = VGIC_ADDR_UNDEF;
423-
}
424422
}
425423

426424
void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
@@ -448,6 +446,11 @@ void kvm_vgic_destroy(struct kvm *kvm)
448446
kvm_vgic_dist_destroy(kvm);
449447

450448
mutex_unlock(&kvm->arch.config_lock);
449+
450+
if (kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3)
451+
kvm_for_each_vcpu(i, vcpu, kvm)
452+
vgic_unregister_redist_iodev(vcpu);
453+
451454
mutex_unlock(&kvm->slots_lock);
452455
}
453456

arch/arm64/kvm/vgic/vgic.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ struct vgic_global kvm_vgic_global_state __ro_after_init = {
3636
* we have to disable IRQs before taking this lock and everything lower
3737
* than it.
3838
*
39+
* The config_lock has additional ordering requirements:
40+
* kvm->slots_lock
41+
* kvm->srcu
42+
* kvm->arch.config_lock
43+
*
3944
* If you need to take multiple locks, always take the upper lock first,
4045
* then the lower ones, e.g. first take the its_lock, then the irq_lock.
4146
* If you are already holding a lock and need to take a higher one, you

arch/arm64/kvm/vgic/vgic.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,4 +346,11 @@ void vgic_v4_configure_vsgis(struct kvm *kvm);
346346
void vgic_v4_get_vlpi_state(struct vgic_irq *irq, bool *val);
347347
int vgic_v4_request_vpe_irq(struct kvm_vcpu *vcpu, int irq);
348348

349+
static inline bool kvm_has_gicv3(struct kvm *kvm)
350+
{
351+
return (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif) &&
352+
irqchip_in_kernel(kvm) &&
353+
kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3);
354+
}
355+
349356
#endif

0 commit comments

Comments
 (0)