lkml.org 
[lkml]   [2008]   [Dec]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 07/12] KVM: change KVM iommu.c to use IOMMU API
    Date
    Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
    ---
    arch/ia64/kvm/Makefile | 2 +-
    arch/x86/include/asm/kvm_host.h | 3 +-
    arch/x86/kvm/Makefile | 2 +-
    virt/kvm/iommu.c | 68 ++++++++++++++++++++-------------------
    virt/kvm/kvm_main.c | 2 +-
    5 files changed, 40 insertions(+), 37 deletions(-)

    diff --git a/arch/ia64/kvm/Makefile b/arch/ia64/kvm/Makefile
    index cb69dfc..0bb99b7 100644
    --- a/arch/ia64/kvm/Makefile
    +++ b/arch/ia64/kvm/Makefile
    @@ -51,7 +51,7 @@ EXTRA_AFLAGS += -Ivirt/kvm -Iarch/ia64/kvm/
    common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \
    coalesced_mmio.o irq_comm.o)

    -ifeq ($(CONFIG_DMAR),y)
    +ifeq ($(CONFIG_IOMMU_API),y)
    common-objs += $(addprefix ../../../virt/kvm/, iommu.o)
    endif

    diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
    index f58f7eb..77f4afa 100644
    --- a/arch/x86/include/asm/kvm_host.h
    +++ b/arch/x86/include/asm/kvm_host.h
    @@ -14,6 +14,7 @@
    #include <linux/types.h>
    #include <linux/mm.h>
    #include <linux/mmu_notifier.h>
    +#include <linux/iommu.h>

    #include <linux/kvm.h>
    #include <linux/kvm_para.h>
    @@ -356,7 +357,7 @@ struct kvm_arch{
    */
    struct list_head active_mmu_pages;
    struct list_head assigned_dev_head;
    - struct dmar_domain *intel_iommu_domain;
    + struct iommu_domain *iommu_domain;
    struct kvm_pic *vpic;
    struct kvm_ioapic *vioapic;
    struct kvm_pit *vpit;
    diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile
    index 00f46c2..d3ec292 100644
    --- a/arch/x86/kvm/Makefile
    +++ b/arch/x86/kvm/Makefile
    @@ -7,7 +7,7 @@ common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \
    ifeq ($(CONFIG_KVM_TRACE),y)
    common-objs += $(addprefix ../../../virt/kvm/, kvm_trace.o)
    endif
    -ifeq ($(CONFIG_DMAR),y)
    +ifeq ($(CONFIG_IOMMU_API),y)
    common-objs += $(addprefix ../../../virt/kvm/, iommu.o)
    endif

    diff --git a/virt/kvm/iommu.c b/virt/kvm/iommu.c
    index 832ee04..110c455 100644
    --- a/virt/kvm/iommu.c
    +++ b/virt/kvm/iommu.c
    @@ -16,15 +16,18 @@
    *
    * Copyright (C) 2006-2008 Intel Corporation
    * Copyright IBM Corporation, 2008
    + * Copyright (C) 2008 Advanced Micro Devices, Inc.
    * Author: Allen M. Kay <allen.m.kay@intel.com>
    * Author: Weidong Han <weidong.han@intel.com>
    * Author: Ben-Ami Yassour <benami@il.ibm.com>
    + * Author: Joerg Roedel <joerg.roedel@amd.com>
    */

    #include <linux/list.h>
    #include <linux/kvm_host.h>
    #include <linux/pci.h>
    #include <linux/dmar.h>
    +#include <linux/iommu.h>
    #include <linux/intel-iommu.h>

    static int kvm_iommu_unmap_memslots(struct kvm *kvm);
    @@ -36,9 +39,9 @@ int kvm_iommu_map_pages(struct kvm *kvm,
    {
    gfn_t gfn = base_gfn;
    pfn_t pfn;
    - int r = 0;
    - unsigned long i;
    - struct dmar_domain *domain = kvm->arch.intel_iommu_domain;
    + phys_addr_t paddr;
    + int i, r = 0;
    + struct iommu_domain *domain = kvm->arch.iommu_domain;

    /* check if iommu exists and in use */
    if (!domain)
    @@ -46,18 +49,13 @@ int kvm_iommu_map_pages(struct kvm *kvm,

    for (i = 0; i < npages; i++) {
    /* check if already mapped */
    - pfn = (pfn_t)intel_iommu_iova_to_pfn(domain,
    - gfn_to_gpa(gfn));
    - if (pfn)
    + paddr = (pfn_t)iommu_iova_to_phys(domain, gfn_to_gpa(gfn));
    + if (paddr)
    kvm_iommu_put_pages(kvm, gfn, 1);

    pfn = gfn_to_pfn(kvm, gfn);
    - r = intel_iommu_map_pages(domain,
    - gfn_to_gpa(gfn),
    - pfn_to_hpa(pfn),
    - PAGE_SIZE,
    - DMA_PTE_READ |
    - DMA_PTE_WRITE);
    + r = iommu_map_range(domain, gfn_to_gpa(gfn), pfn_to_hpa(pfn),
    + PAGE_SIZE, DMA_PTE_READ | DMA_PTE_WRITE);
    if (r) {
    printk(KERN_ERR "kvm_iommu_map_pages:"
    "iommu failed to map pfn=%lx\n", pfn);
    @@ -91,7 +89,7 @@ int kvm_assign_device(struct kvm *kvm,
    struct kvm_assigned_dev_kernel *assigned_dev)
    {
    struct pci_dev *pdev = NULL;
    - struct dmar_domain *domain = kvm->arch.intel_iommu_domain;
    + struct iommu_domain *domain = kvm->arch.iommu_domain;
    int r;

    /* check if iommu exists and in use */
    @@ -102,7 +100,12 @@ int kvm_assign_device(struct kvm *kvm,
    if (pdev == NULL)
    return -ENODEV;

    - r = intel_iommu_assign_device(domain, pdev);
    + if (!iommu_found()) {
    + printk(KERN_ERR "%s: No IOMMU found\n", __func__);
    + return -ENODEV;
    + }
    +
    + r = iommu_attach_device(domain, &pdev->dev);
    if (r) {
    printk(KERN_ERR "assign device %x:%x.%x failed",
    pdev->bus->number,
    @@ -111,7 +114,7 @@ int kvm_assign_device(struct kvm *kvm,
    return r;
    }

    - printk(KERN_DEBUG "assign device: host bdf = %x:%x:%x\n",
    + printk(KERN_DEBUG "KVM IOMMU direct map: host bdf = %x:%x:%x\n",
    assigned_dev->host_busnr,
    PCI_SLOT(assigned_dev->host_devfn),
    PCI_FUNC(assigned_dev->host_devfn));
    @@ -122,7 +125,7 @@ int kvm_assign_device(struct kvm *kvm,
    int kvm_deassign_device(struct kvm *kvm,
    struct kvm_assigned_dev_kernel *assigned_dev)
    {
    - struct dmar_domain *domain = kvm->arch.intel_iommu_domain;
    + struct iommu_domain *domain = kvm->arch.iommu_domain;
    struct pci_dev *pdev = NULL;

    /* check if iommu exists and in use */
    @@ -133,7 +136,7 @@ int kvm_deassign_device(struct kvm *kvm,
    if (pdev == NULL)
    return -ENODEV;

    - intel_iommu_deassign_device(domain, pdev);
    + iommu_detach_device(domain, &pdev->dev);

    printk(KERN_DEBUG "deassign device: host bdf = %x:%x:%x\n",
    assigned_dev->host_busnr,
    @@ -147,13 +150,13 @@ int kvm_iommu_map_guest(struct kvm *kvm)
    {
    int r;

    - if (!intel_iommu_found()) {
    - printk(KERN_ERR "%s: intel iommu not found\n", __func__);
    + if (!iommu_found()) {
    + printk(KERN_ERR "%s: iommu not found\n", __func__);
    return -ENODEV;
    }

    - kvm->arch.intel_iommu_domain = intel_iommu_alloc_domain();
    - if (!kvm->arch.intel_iommu_domain)
    + kvm->arch.iommu_domain = iommu_domain_alloc();
    + if (!kvm->arch.iommu_domain)
    return -ENOMEM;

    r = kvm_iommu_map_memslots(kvm);
    @@ -171,8 +174,8 @@ static void kvm_iommu_put_pages(struct kvm *kvm,
    gfn_t base_gfn, unsigned long npages)
    {
    gfn_t gfn = base_gfn;
    - pfn_t pfn;
    - struct dmar_domain *domain = kvm->arch.intel_iommu_domain;
    + phys_addr_t paddr;
    + struct iommu_domain *domain = kvm->arch.iommu_domain;
    unsigned long i;

    /* check if iommu exists and in use */
    @@ -180,15 +183,12 @@ static void kvm_iommu_put_pages(struct kvm *kvm,
    return;

    for (i = 0; i < npages; i++) {
    - pfn = (pfn_t)intel_iommu_iova_to_pfn(domain,
    - gfn_to_gpa(gfn));
    - kvm_release_pfn_clean(pfn);
    + paddr = iommu_iova_to_phys(domain, gfn_to_gpa(gfn));
    + kvm_release_pfn_clean(paddr >> PAGE_SHIFT);
    gfn++;
    }

    - intel_iommu_unmap_pages(domain,
    - gfn_to_gpa(base_gfn),
    - PAGE_SIZE * npages);
    + iommu_unmap_range(domain, gfn_to_gpa(base_gfn), PAGE_SIZE * npages);
    }

    static int kvm_iommu_unmap_memslots(struct kvm *kvm)
    @@ -207,22 +207,24 @@ static int kvm_iommu_unmap_memslots(struct kvm *kvm)
    int kvm_iommu_unmap_guest(struct kvm *kvm)
    {
    struct kvm_assigned_dev_kernel *entry;
    - struct dmar_domain *domain = kvm->arch.intel_iommu_domain;
    + struct iommu_domain *domain = kvm->arch.iommu_domain;

    /* check if iommu exists and in use */
    if (!domain)
    return 0;

    list_for_each_entry(entry, &kvm->arch.assigned_dev_head, list) {
    - printk(KERN_DEBUG "VT-d unmap: host bdf = %x:%x:%x\n",
    + struct pci_dev *pdev = entry->dev;
    + printk(KERN_DEBUG "IOMMU unmap: host bdf = %x:%x:%x\n",
    entry->host_busnr,
    PCI_SLOT(entry->host_devfn),
    PCI_FUNC(entry->host_devfn));

    /* detach kvm dmar domain */
    - intel_iommu_deassign_device(domain, entry->dev);
    + iommu_detach_device(domain, &pdev->dev);
    }
    kvm_iommu_unmap_memslots(kvm);
    - intel_iommu_free_domain(domain);
    + iommu_domain_free(domain);
    +
    return 0;
    }
    diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
    index fe6aba0..397ad0f 100644
    --- a/virt/kvm/kvm_main.c
    +++ b/virt/kvm/kvm_main.c
    @@ -472,7 +472,7 @@ static int kvm_vm_ioctl_assign_device(struct kvm *kvm,
    list_add(&match->list, &kvm->arch.assigned_dev_head);

    if (assigned_dev->flags & KVM_DEV_ASSIGN_ENABLE_IOMMU) {
    - if (!kvm->arch.intel_iommu_domain) {
    + if (!kvm->arch.iommu_domain) {
    r = kvm_iommu_map_guest(kvm);
    if (r)
    goto out_list_del;
    --
    1.5.6.4



    \
     
     \ /
      Last update: 2008-12-02 14:09    [W:2.633 / U:0.436 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site