aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorAlex Williamson <alex.williamson@redhat.com>2013-10-30 13:02:30 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2013-10-30 14:02:23 -0400
commite0f0bbc527f6e9c0261f1d16b2a0b47612b7f235 (patch)
tree623b954e7571767c4d5f0581ad8ba6eacd48785d /arch/x86
parentd96eb2c6f480769bff32054e78b964860dae4d56 (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.h2
-rw-r--r--arch/x86/kvm/vmx.c3
-rw-r--r--arch/x86/kvm/x86.c22
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
2719static bool need_emulate_wbinvd(struct kvm_vcpu *vcpu) 2719static 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
2725void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) 2724void 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
7440void kvm_arch_register_noncoherent_dma(struct kvm *kvm)
7441{
7442 atomic_inc(&kvm->arch.noncoherent_dma_count);
7443}
7444EXPORT_SYMBOL_GPL(kvm_arch_register_noncoherent_dma);
7445
7446void kvm_arch_unregister_noncoherent_dma(struct kvm *kvm)
7447{
7448 atomic_dec(&kvm->arch.noncoherent_dma_count);
7449}
7450EXPORT_SYMBOL_GPL(kvm_arch_unregister_noncoherent_dma);
7451
7452bool kvm_arch_has_noncoherent_dma(struct kvm *kvm)
7453{
7454 return atomic_read(&kvm->arch.noncoherent_dma_count);
7455}
7456EXPORT_SYMBOL_GPL(kvm_arch_has_noncoherent_dma);
7457
7440EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_exit); 7458EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_exit);
7441EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_inj_virq); 7459EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_inj_virq);
7442EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_page_fault); 7460EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_page_fault);