diff options
author | Alex Williamson <alex.williamson@redhat.com> | 2013-10-30 13:02:30 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2013-10-30 14:02:23 -0400 |
commit | e0f0bbc527f6e9c0261f1d16b2a0b47612b7f235 (patch) | |
tree | 623b954e7571767c4d5f0581ad8ba6eacd48785d /arch/x86 | |
parent | d96eb2c6f480769bff32054e78b964860dae4d56 (diff) |
kvm: Create non-coherent DMA registeration
We currently use some ad-hoc arch variables tied to legacy KVM device
assignment to manage emulation of instructions that depend on whether
non-coherent DMA is present. Create an interface for this, adapting
legacy KVM device assignment and adding VFIO via the KVM-VFIO device.
For now we assume that non-coherent DMA is possible any time we have a
VFIO group. Eventually an interface can be developed as part of the
VFIO external user interface to query the coherency of a group.
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/include/asm/kvm_host.h | 2 | ||||
-rw-r--r-- | arch/x86/kvm/vmx.c | 3 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 22 |
3 files changed, 23 insertions, 4 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 91b35e4005d3..de388c55e7ec 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
@@ -565,6 +565,8 @@ struct kvm_arch { | |||
565 | struct list_head assigned_dev_head; | 565 | struct list_head assigned_dev_head; |
566 | struct iommu_domain *iommu_domain; | 566 | struct iommu_domain *iommu_domain; |
567 | bool iommu_noncoherent; | 567 | bool iommu_noncoherent; |
568 | #define __KVM_HAVE_ARCH_NONCOHERENT_DMA | ||
569 | atomic_t noncoherent_dma_count; | ||
568 | struct kvm_pic *vpic; | 570 | struct kvm_pic *vpic; |
569 | struct kvm_ioapic *vioapic; | 571 | struct kvm_ioapic *vioapic; |
570 | struct kvm_pit *vpit; | 572 | struct kvm_pit *vpit; |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 727a5e980c43..fabf7421ec18 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -7445,8 +7445,7 @@ static u64 vmx_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio) | |||
7445 | */ | 7445 | */ |
7446 | if (is_mmio) | 7446 | if (is_mmio) |
7447 | ret = MTRR_TYPE_UNCACHABLE << VMX_EPT_MT_EPTE_SHIFT; | 7447 | ret = MTRR_TYPE_UNCACHABLE << VMX_EPT_MT_EPTE_SHIFT; |
7448 | else if (vcpu->kvm->arch.iommu_domain && | 7448 | else if (kvm_arch_has_noncoherent_dma(vcpu->kvm)) |
7449 | vcpu->kvm->arch.iommu_noncoherent) | ||
7450 | ret = kvm_get_guest_memory_type(vcpu, gfn) << | 7449 | ret = kvm_get_guest_memory_type(vcpu, gfn) << |
7451 | VMX_EPT_MT_EPTE_SHIFT; | 7450 | VMX_EPT_MT_EPTE_SHIFT; |
7452 | else | 7451 | else |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 92ad83e5b132..ec35d09937da 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -2718,8 +2718,7 @@ static void wbinvd_ipi(void *garbage) | |||
2718 | 2718 | ||
2719 | static bool need_emulate_wbinvd(struct kvm_vcpu *vcpu) | 2719 | static bool need_emulate_wbinvd(struct kvm_vcpu *vcpu) |
2720 | { | 2720 | { |
2721 | return vcpu->kvm->arch.iommu_domain && | 2721 | return kvm_arch_has_noncoherent_dma(vcpu->kvm); |
2722 | vcpu->kvm->arch.iommu_noncoherent; | ||
2723 | } | 2722 | } |
2724 | 2723 | ||
2725 | void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | 2724 | void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) |
@@ -6998,6 +6997,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) | |||
6998 | INIT_LIST_HEAD(&kvm->arch.active_mmu_pages); | 6997 | INIT_LIST_HEAD(&kvm->arch.active_mmu_pages); |
6999 | INIT_LIST_HEAD(&kvm->arch.zapped_obsolete_pages); | 6998 | INIT_LIST_HEAD(&kvm->arch.zapped_obsolete_pages); |
7000 | INIT_LIST_HEAD(&kvm->arch.assigned_dev_head); | 6999 | INIT_LIST_HEAD(&kvm->arch.assigned_dev_head); |
7000 | atomic_set(&kvm->arch.noncoherent_dma_count, 0); | ||
7001 | 7001 | ||
7002 | /* Reserve bit 0 of irq_sources_bitmap for userspace irq source */ | 7002 | /* Reserve bit 0 of irq_sources_bitmap for userspace irq source */ |
7003 | set_bit(KVM_USERSPACE_IRQ_SOURCE_ID, &kvm->arch.irq_sources_bitmap); | 7003 | set_bit(KVM_USERSPACE_IRQ_SOURCE_ID, &kvm->arch.irq_sources_bitmap); |
@@ -7437,6 +7437,24 @@ bool kvm_arch_can_inject_async_page_present(struct kvm_vcpu *vcpu) | |||
7437 | kvm_x86_ops->interrupt_allowed(vcpu); | 7437 | kvm_x86_ops->interrupt_allowed(vcpu); |
7438 | } | 7438 | } |
7439 | 7439 | ||
7440 | void kvm_arch_register_noncoherent_dma(struct kvm *kvm) | ||
7441 | { | ||
7442 | atomic_inc(&kvm->arch.noncoherent_dma_count); | ||
7443 | } | ||
7444 | EXPORT_SYMBOL_GPL(kvm_arch_register_noncoherent_dma); | ||
7445 | |||
7446 | void kvm_arch_unregister_noncoherent_dma(struct kvm *kvm) | ||
7447 | { | ||
7448 | atomic_dec(&kvm->arch.noncoherent_dma_count); | ||
7449 | } | ||
7450 | EXPORT_SYMBOL_GPL(kvm_arch_unregister_noncoherent_dma); | ||
7451 | |||
7452 | bool kvm_arch_has_noncoherent_dma(struct kvm *kvm) | ||
7453 | { | ||
7454 | return atomic_read(&kvm->arch.noncoherent_dma_count); | ||
7455 | } | ||
7456 | EXPORT_SYMBOL_GPL(kvm_arch_has_noncoherent_dma); | ||
7457 | |||
7440 | EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_exit); | 7458 | EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_exit); |
7441 | EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_inj_virq); | 7459 | EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_inj_virq); |
7442 | EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_page_fault); | 7460 | EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_page_fault); |