Commit b2f31717 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull kvm fixes from Paolo Bonzini:
 "ARM64:

   - 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.

  x86:

   - A command line parsing fix and a clang compilation fix for
     selftests

   - A fix for a longstanding VMX issue, that surprisingly was only
     found now to affect real world guests"

* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm:
  KVM: selftests: Make reclaim_period_ms input always be positive
  KVM: x86/vmx: Do not skip segment attributes if unusable bit is set
  selftests: kvm: move declaration at the beginning of main()
  KVM: arm64: GICv4.1: Fix race with doorbell on VPE activation/deactivation
  KVM: arm64: Pass the actual page address to mte_clear_page_tags()
parents 02db81a7 c2c46b10
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1079,7 +1079,7 @@ long kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm,

			/* uaccess failed, don't leave stale tags */
			if (num_tags != MTE_GRANULES_PER_PAGE)
				mte_clear_page_tags(page);
				mte_clear_page_tags(maddr);
			set_page_mte_tagged(page);

			kvm_release_pfn_dirty(pfn);
+11 −14
Original line number Diff line number Diff line
@@ -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
 * 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;

	for (i = 0; i < dist->its_vm.nr_vpes; i++) {
		desc = irq_to_desc(dist->its_vm.vpes[i]->irq);
		irq_domain_deactivate_irq(irq_desc_get_irq_data(desc));
	}
	for (i = 0; i < dist->its_vm.nr_vpes; i++)
		free_irq(dist->its_vm.vpes[i]->irq, kvm_get_vcpu(kvm, i));
}

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;

	for (i = 0; i < dist->its_vm.nr_vpes; i++) {
		desc = irq_to_desc(dist->its_vm.vpes[i]->irq);
		irq_domain_activate_irq(irq_desc_get_irq_data(desc), false);
	}
	for (i = 0; i < dist->its_vm.nr_vpes; i++)
		WARN_ON(vgic_v4_request_vpe_irq(kvm_get_vcpu(kvm, i),
						dist->its_vm.vpes[i]->irq));
}

/**
@@ -394,7 +391,7 @@ int vgic_v3_save_pending_tables(struct kvm *kvm)
	 * and enabling of the doorbells have already been done.
	 */
	if (kvm_vgic_global_state.has_gicv4_1) {
		unmap_all_vpes(dist);
		unmap_all_vpes(kvm);
		vlpi_avail = true;
	}

@@ -444,7 +441,7 @@ int vgic_v3_save_pending_tables(struct kvm *kvm)

out:
	if (vlpi_avail)
		map_all_vpes(dist);
		map_all_vpes(kvm);

	return ret;
}
+6 −2
Original line number Diff line number Diff line
@@ -222,6 +222,11 @@ void vgic_v4_get_vlpi_state(struct vgic_irq *irq, bool *val)
	*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
 * @kvm:	Pointer to the VM being initialized
@@ -283,8 +288,7 @@ int vgic_v4_init(struct kvm *kvm)
			irq_flags &= ~IRQ_NOAUTOEN;
		irq_set_status_flags(irq, irq_flags);

		ret = request_irq(irq, vgic_v4_doorbell_handler,
				  0, "vcpu", vcpu);
		ret = vgic_v4_request_vpe_irq(vcpu, irq);
		if (ret) {
			kvm_err("failed to allocate vcpu IRQ%d\n", irq);
			/*
+1 −0
Original line number Diff line number Diff line
@@ -331,5 +331,6 @@ int vgic_v4_init(struct kvm *kvm);
void vgic_v4_teardown(struct kvm *kvm);
void vgic_v4_configure_vsgis(struct kvm *kvm);
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
+9 −12
Original line number Diff line number Diff line
@@ -3440,9 +3440,6 @@ static u32 vmx_segment_access_rights(struct kvm_segment *var)
{
	u32 ar;

	if (var->unusable || !var->present)
		ar = 1 << 16;
	else {
	ar = var->type & 15;
	ar |= (var->s & 1) << 4;
	ar |= (var->dpl & 3) << 5;
@@ -3451,7 +3448,7 @@ static u32 vmx_segment_access_rights(struct kvm_segment *var)
	ar |= (var->l & 1) << 13;
	ar |= (var->db & 1) << 14;
	ar |= (var->g & 1) << 15;
	}
	ar |= (var->unusable || !var->present) << 16;

	return ar;
}
Loading