Commit d732cbf7 authored by Paolo Bonzini's avatar Paolo Bonzini

Merge tag 'kvmarm-fixes-6.2-2' of...

Merge tag 'kvmarm-fixes-6.2-2' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD

KVM/arm64 fixes for 6.2, take #2

- Pass the correct address to mte_clear_page_tags() on initialising
  a tagged page

- Plug a race against a GICv4.1 doorbell interrupt while saving
  the vgic-v3 pending state.
parents 2241ab53 ef369168
...@@ -1079,7 +1079,7 @@ long kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm, ...@@ -1079,7 +1079,7 @@ long kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm,
/* uaccess failed, don't leave stale tags */ /* uaccess failed, don't leave stale tags */
if (num_tags != MTE_GRANULES_PER_PAGE) if (num_tags != MTE_GRANULES_PER_PAGE)
mte_clear_page_tags(page); mte_clear_page_tags(maddr);
set_page_mte_tagged(page); set_page_mte_tagged(page);
kvm_release_pfn_dirty(pfn); kvm_release_pfn_dirty(pfn);
......
...@@ -350,26 +350,23 @@ int vgic_v3_lpi_sync_pending_status(struct kvm *kvm, struct vgic_irq *irq) ...@@ -350,26 +350,23 @@ int vgic_v3_lpi_sync_pending_status(struct kvm *kvm, struct vgic_irq *irq)
* The deactivation of the doorbell interrupt will trigger the * The deactivation of the doorbell interrupt will trigger the
* unmapping of the associated vPE. * unmapping of the associated vPE.
*/ */
static void unmap_all_vpes(struct vgic_dist *dist) static void unmap_all_vpes(struct kvm *kvm)
{ {
struct irq_desc *desc; struct vgic_dist *dist = &kvm->arch.vgic;
int i; int i;
for (i = 0; i < dist->its_vm.nr_vpes; i++) { for (i = 0; i < dist->its_vm.nr_vpes; i++)
desc = irq_to_desc(dist->its_vm.vpes[i]->irq); free_irq(dist->its_vm.vpes[i]->irq, kvm_get_vcpu(kvm, i));
irq_domain_deactivate_irq(irq_desc_get_irq_data(desc));
}
} }
static void map_all_vpes(struct vgic_dist *dist) static void map_all_vpes(struct kvm *kvm)
{ {
struct irq_desc *desc; struct vgic_dist *dist = &kvm->arch.vgic;
int i; int i;
for (i = 0; i < dist->its_vm.nr_vpes; i++) { for (i = 0; i < dist->its_vm.nr_vpes; i++)
desc = irq_to_desc(dist->its_vm.vpes[i]->irq); WARN_ON(vgic_v4_request_vpe_irq(kvm_get_vcpu(kvm, i),
irq_domain_activate_irq(irq_desc_get_irq_data(desc), false); dist->its_vm.vpes[i]->irq));
}
} }
/** /**
...@@ -394,7 +391,7 @@ int vgic_v3_save_pending_tables(struct kvm *kvm) ...@@ -394,7 +391,7 @@ int vgic_v3_save_pending_tables(struct kvm *kvm)
* and enabling of the doorbells have already been done. * and enabling of the doorbells have already been done.
*/ */
if (kvm_vgic_global_state.has_gicv4_1) { if (kvm_vgic_global_state.has_gicv4_1) {
unmap_all_vpes(dist); unmap_all_vpes(kvm);
vlpi_avail = true; vlpi_avail = true;
} }
...@@ -444,7 +441,7 @@ int vgic_v3_save_pending_tables(struct kvm *kvm) ...@@ -444,7 +441,7 @@ int vgic_v3_save_pending_tables(struct kvm *kvm)
out: out:
if (vlpi_avail) if (vlpi_avail)
map_all_vpes(dist); map_all_vpes(kvm);
return ret; return ret;
} }
......
...@@ -222,6 +222,11 @@ void vgic_v4_get_vlpi_state(struct vgic_irq *irq, bool *val) ...@@ -222,6 +222,11 @@ void vgic_v4_get_vlpi_state(struct vgic_irq *irq, bool *val)
*val = !!(*ptr & mask); *val = !!(*ptr & mask);
} }
int vgic_v4_request_vpe_irq(struct kvm_vcpu *vcpu, int irq)
{
return request_irq(irq, vgic_v4_doorbell_handler, 0, "vcpu", vcpu);
}
/** /**
* vgic_v4_init - Initialize the GICv4 data structures * vgic_v4_init - Initialize the GICv4 data structures
* @kvm: Pointer to the VM being initialized * @kvm: Pointer to the VM being initialized
...@@ -283,8 +288,7 @@ int vgic_v4_init(struct kvm *kvm) ...@@ -283,8 +288,7 @@ int vgic_v4_init(struct kvm *kvm)
irq_flags &= ~IRQ_NOAUTOEN; irq_flags &= ~IRQ_NOAUTOEN;
irq_set_status_flags(irq, irq_flags); irq_set_status_flags(irq, irq_flags);
ret = request_irq(irq, vgic_v4_doorbell_handler, ret = vgic_v4_request_vpe_irq(vcpu, irq);
0, "vcpu", vcpu);
if (ret) { if (ret) {
kvm_err("failed to allocate vcpu IRQ%d\n", irq); kvm_err("failed to allocate vcpu IRQ%d\n", irq);
/* /*
......
...@@ -331,5 +331,6 @@ int vgic_v4_init(struct kvm *kvm); ...@@ -331,5 +331,6 @@ int vgic_v4_init(struct kvm *kvm);
void vgic_v4_teardown(struct kvm *kvm); void vgic_v4_teardown(struct kvm *kvm);
void vgic_v4_configure_vsgis(struct kvm *kvm); void vgic_v4_configure_vsgis(struct kvm *kvm);
void vgic_v4_get_vlpi_state(struct vgic_irq *irq, bool *val); void vgic_v4_get_vlpi_state(struct vgic_irq *irq, bool *val);
int vgic_v4_request_vpe_irq(struct kvm_vcpu *vcpu, int irq);
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment