linux/drivers/vfio/vfio_iommu_type1.c
<<
>>
Prefs
   1/*
   2 * VFIO: IOMMU DMA mapping support for Type1 IOMMU
   3 *
   4 * Copyright (C) 2012 Red Hat, Inc.  All rights reserved.
   5 *     Author: Alex Williamson <alex.williamson@redhat.com>
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License version 2 as
   9 * published by the Free Software Foundation.
  10 *
  11 * Derived from original vfio:
  12 * Copyright 2010 Cisco Systems, Inc.  All rights reserved.
  13 * Author: Tom Lyon, pugs@cisco.com
  14 *
  15 * We arbitrarily define a Type1 IOMMU as one matching the below code.
  16 * It could be called the x86 IOMMU as it's designed for AMD-Vi & Intel
  17 * VT-d, but that makes it harder to re-use as theoretically anyone
  18 * implementing a similar IOMMU could make use of this.  We expect the
  19 * IOMMU to support the IOMMU API and have few to no restrictions around
  20 * the IOVA range that can be mapped.  The Type1 IOMMU is currently
  21 * optimized for relatively static mappings of a userspace process with
  22 * userpsace pages pinned into memory.  We also assume devices and IOMMU
  23 * domains are PCI based as the IOMMU API is still centered around a
  24 * device/bus interface rather than a group interface.
  25 */
  26
  27#include <linux/compat.h>
  28#include <linux/device.h>
  29#include <linux/fs.h>
  30#include <linux/iommu.h>
  31#include <linux/module.h>
  32#include <linux/mm.h>
  33#include <linux/pci.h>          /* pci_bus_type */
  34#include <linux/sched.h>
  35#include <linux/slab.h>
  36#include <linux/uaccess.h>
  37#include <linux/vfio.h>
  38#include <linux/workqueue.h>
  39
  40#define DRIVER_VERSION  "0.2"
  41#define DRIVER_AUTHOR   "Alex Williamson <alex.williamson@redhat.com>"
  42#define DRIVER_DESC     "Type1 IOMMU driver for VFIO"
  43
  44static bool allow_unsafe_interrupts;
  45module_param_named(allow_unsafe_interrupts,
  46                   allow_unsafe_interrupts, bool, S_IRUGO | S_IWUSR);
  47MODULE_PARM_DESC(allow_unsafe_interrupts,
  48                 "Enable VFIO IOMMU support for on platforms without interrupt remapping support.");
  49
  50struct vfio_iommu {
  51        struct iommu_domain     *domain;
  52        struct mutex            lock;
  53        struct list_head        dma_list;
  54        struct list_head        group_list;
  55        bool                    cache;
  56};
  57
  58struct vfio_dma {
  59        struct list_head        next;
  60        dma_addr_t              iova;           /* Device address */
  61        unsigned long           vaddr;          /* Process virtual addr */
  62        long                    npage;          /* Number of pages */
  63        int                     prot;           /* IOMMU_READ/WRITE */
  64};
  65
  66struct vfio_group {
  67        struct iommu_group      *iommu_group;
  68        struct list_head        next;
  69};
  70
  71/*
  72 * This code handles mapping and unmapping of user data buffers
  73 * into DMA'ble space using the IOMMU
  74 */
  75
  76#define NPAGE_TO_SIZE(npage)    ((size_t)(npage) << PAGE_SHIFT)
  77
  78struct vwork {
  79        struct mm_struct        *mm;
  80        long                    npage;
  81        struct work_struct      work;
  82};
  83
  84/* delayed decrement/increment for locked_vm */
  85static void vfio_lock_acct_bg(struct work_struct *work)
  86{
  87        struct vwork *vwork = container_of(work, struct vwork, work);
  88        struct mm_struct *mm;
  89
  90        mm = vwork->mm;
  91        down_write(&mm->mmap_sem);
  92        mm->locked_vm += vwork->npage;
  93        up_write(&mm->mmap_sem);
  94        mmput(mm);
  95        kfree(vwork);
  96}
  97
  98static void vfio_lock_acct(long npage)
  99{
 100        struct vwork *vwork;
 101        struct mm_struct *mm;
 102
 103        if (!current->mm)
 104                return; /* process exited */
 105
 106        if (down_write_trylock(&current->mm->mmap_sem)) {
 107                current->mm->locked_vm += npage;
 108                up_write(&current->mm->mmap_sem);
 109                return;
 110        }
 111
 112        /*
 113         * Couldn't get mmap_sem lock, so must setup to update
 114         * mm->locked_vm later. If locked_vm were atomic, we
 115         * wouldn't need this silliness
 116         */
 117        vwork = kmalloc(sizeof(struct vwork), GFP_KERNEL);
 118        if (!vwork)
 119                return;
 120        mm = get_task_mm(current);
 121        if (!mm) {
 122                kfree(vwork);
 123                return;
 124        }
 125        INIT_WORK(&vwork->work, vfio_lock_acct_bg);
 126        vwork->mm = mm;
 127        vwork->npage = npage;
 128        schedule_work(&vwork->work);
 129}
 130
 131/*
 132 * Some mappings aren't backed by a struct page, for example an mmap'd
 133 * MMIO range for our own or another device.  These use a different
 134 * pfn conversion and shouldn't be tracked as locked pages.
 135 */
 136static bool is_invalid_reserved_pfn(unsigned long pfn)
 137{
 138        if (pfn_valid(pfn)) {
 139                bool reserved;
 140                struct page *tail = pfn_to_page(pfn);
 141                struct page *head = compound_trans_head(tail);
 142                reserved = !!(PageReserved(head));
 143                if (head != tail) {
 144                        /*
 145                         * "head" is not a dangling pointer
 146                         * (compound_trans_head takes care of that)
 147                         * but the hugepage may have been split
 148                         * from under us (and we may not hold a
 149                         * reference count on the head page so it can
 150                         * be reused before we run PageReferenced), so
 151                         * we've to check PageTail before returning
 152                         * what we just read.
 153                         */
 154                        smp_rmb();
 155                        if (PageTail(tail))
 156                                return reserved;
 157                }
 158                return PageReserved(tail);
 159        }
 160
 161        return true;
 162}
 163
 164static int put_pfn(unsigned long pfn, int prot)
 165{
 166        if (!is_invalid_reserved_pfn(pfn)) {
 167                struct page *page = pfn_to_page(pfn);
 168                if (prot & IOMMU_WRITE)
 169                        SetPageDirty(page);
 170                put_page(page);
 171                return 1;
 172        }
 173        return 0;
 174}
 175
 176/* Unmap DMA region */
 177static long __vfio_dma_do_unmap(struct vfio_iommu *iommu, dma_addr_t iova,
 178                             long npage, int prot)
 179{
 180        long i, unlocked = 0;
 181
 182        for (i = 0; i < npage; i++, iova += PAGE_SIZE) {
 183                unsigned long pfn;
 184
 185                pfn = iommu_iova_to_phys(iommu->domain, iova) >> PAGE_SHIFT;
 186                if (pfn) {
 187                        iommu_unmap(iommu->domain, iova, PAGE_SIZE);
 188                        unlocked += put_pfn(pfn, prot);
 189                }
 190        }
 191        return unlocked;
 192}
 193
 194static void vfio_dma_unmap(struct vfio_iommu *iommu, dma_addr_t iova,
 195                           long npage, int prot)
 196{
 197        long unlocked;
 198
 199        unlocked = __vfio_dma_do_unmap(iommu, iova, npage, prot);
 200        vfio_lock_acct(-unlocked);
 201}
 202
 203static int vaddr_get_pfn(unsigned long vaddr, int prot, unsigned long *pfn)
 204{
 205        struct page *page[1];
 206        struct vm_area_struct *vma;
 207        int ret = -EFAULT;
 208
 209        if (get_user_pages_fast(vaddr, 1, !!(prot & IOMMU_WRITE), page) == 1) {
 210                *pfn = page_to_pfn(page[0]);
 211                return 0;
 212        }
 213
 214        down_read(&current->mm->mmap_sem);
 215
 216        vma = find_vma_intersection(current->mm, vaddr, vaddr + 1);
 217
 218        if (vma && vma->vm_flags & VM_PFNMAP) {
 219                *pfn = ((vaddr - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
 220                if (is_invalid_reserved_pfn(*pfn))
 221                        ret = 0;
 222        }
 223
 224        up_read(&current->mm->mmap_sem);
 225
 226        return ret;
 227}
 228
 229/* Map DMA region */
 230static int __vfio_dma_map(struct vfio_iommu *iommu, dma_addr_t iova,
 231                          unsigned long vaddr, long npage, int prot)
 232{
 233        dma_addr_t start = iova;
 234        long i, locked = 0;
 235        int ret;
 236
 237        /* Verify that pages are not already mapped */
 238        for (i = 0; i < npage; i++, iova += PAGE_SIZE)
 239                if (iommu_iova_to_phys(iommu->domain, iova))
 240                        return -EBUSY;
 241
 242        iova = start;
 243
 244        if (iommu->cache)
 245                prot |= IOMMU_CACHE;
 246
 247        /*
 248         * XXX We break mappings into pages and use get_user_pages_fast to
 249         * pin the pages in memory.  It's been suggested that mlock might
 250         * provide a more efficient mechanism, but nothing prevents the
 251         * user from munlocking the pages, which could then allow the user
 252         * access to random host memory.  We also have no guarantee from the
 253         * IOMMU API that the iommu driver can unmap sub-pages of previous
 254         * mappings.  This means we might lose an entire range if a single
 255         * page within it is unmapped.  Single page mappings are inefficient,
 256         * but provide the most flexibility for now.
 257         */
 258        for (i = 0; i < npage; i++, iova += PAGE_SIZE, vaddr += PAGE_SIZE) {
 259                unsigned long pfn = 0;
 260
 261                ret = vaddr_get_pfn(vaddr, prot, &pfn);
 262                if (ret) {
 263                        __vfio_dma_do_unmap(iommu, start, i, prot);
 264                        return ret;
 265                }
 266
 267                /*
 268                 * Only add actual locked pages to accounting
 269                 * XXX We're effectively marking a page locked for every
 270                 * IOVA page even though it's possible the user could be
 271                 * backing multiple IOVAs with the same vaddr.  This over-
 272                 * penalizes the user process, but we currently have no
 273                 * easy way to do this properly.
 274                 */
 275                if (!is_invalid_reserved_pfn(pfn))
 276                        locked++;
 277
 278                ret = iommu_map(iommu->domain, iova,
 279                                (phys_addr_t)pfn << PAGE_SHIFT,
 280                                PAGE_SIZE, prot);
 281                if (ret) {
 282                        /* Back out mappings on error */
 283                        put_pfn(pfn, prot);
 284                        __vfio_dma_do_unmap(iommu, start, i, prot);
 285                        return ret;
 286                }
 287        }
 288        vfio_lock_acct(locked);
 289        return 0;
 290}
 291
 292static inline bool ranges_overlap(dma_addr_t start1, size_t size1,
 293                                  dma_addr_t start2, size_t size2)
 294{
 295        if (start1 < start2)
 296                return (start2 - start1 < size1);
 297        else if (start2 < start1)
 298                return (start1 - start2 < size2);
 299        return (size1 > 0 && size2 > 0);
 300}
 301
 302static struct vfio_dma *vfio_find_dma(struct vfio_iommu *iommu,
 303                                                dma_addr_t start, size_t size)
 304{
 305        struct vfio_dma *dma;
 306
 307        list_for_each_entry(dma, &iommu->dma_list, next) {
 308                if (ranges_overlap(dma->iova, NPAGE_TO_SIZE(dma->npage),
 309                                   start, size))
 310                        return dma;
 311        }
 312        return NULL;
 313}
 314
 315static long vfio_remove_dma_overlap(struct vfio_iommu *iommu, dma_addr_t start,
 316                                    size_t size, struct vfio_dma *dma)
 317{
 318        struct vfio_dma *split;
 319        long npage_lo, npage_hi;
 320
 321        /* Existing dma region is completely covered, unmap all */
 322        if (start <= dma->iova &&
 323            start + size >= dma->iova + NPAGE_TO_SIZE(dma->npage)) {
 324                vfio_dma_unmap(iommu, dma->iova, dma->npage, dma->prot);
 325                list_del(&dma->next);
 326                npage_lo = dma->npage;
 327                kfree(dma);
 328                return npage_lo;
 329        }
 330
 331        /* Overlap low address of existing range */
 332        if (start <= dma->iova) {
 333                size_t overlap;
 334
 335                overlap = start + size - dma->iova;
 336                npage_lo = overlap >> PAGE_SHIFT;
 337
 338                vfio_dma_unmap(iommu, dma->iova, npage_lo, dma->prot);
 339                dma->iova += overlap;
 340                dma->vaddr += overlap;
 341                dma->npage -= npage_lo;
 342                return npage_lo;
 343        }
 344
 345        /* Overlap high address of existing range */
 346        if (start + size >= dma->iova + NPAGE_TO_SIZE(dma->npage)) {
 347                size_t overlap;
 348
 349                overlap = dma->iova + NPAGE_TO_SIZE(dma->npage) - start;
 350                npage_hi = overlap >> PAGE_SHIFT;
 351
 352                vfio_dma_unmap(iommu, start, npage_hi, dma->prot);
 353                dma->npage -= npage_hi;
 354                return npage_hi;
 355        }
 356
 357        /* Split existing */
 358        npage_lo = (start - dma->iova) >> PAGE_SHIFT;
 359        npage_hi = dma->npage - (size >> PAGE_SHIFT) - npage_lo;
 360
 361        split = kzalloc(sizeof *split, GFP_KERNEL);
 362        if (!split)
 363                return -ENOMEM;
 364
 365        vfio_dma_unmap(iommu, start, size >> PAGE_SHIFT, dma->prot);
 366
 367        dma->npage = npage_lo;
 368
 369        split->npage = npage_hi;
 370        split->iova = start + size;
 371        split->vaddr = dma->vaddr + NPAGE_TO_SIZE(npage_lo) + size;
 372        split->prot = dma->prot;
 373        list_add(&split->next, &iommu->dma_list);
 374        return size >> PAGE_SHIFT;
 375}
 376
 377static int vfio_dma_do_unmap(struct vfio_iommu *iommu,
 378                             struct vfio_iommu_type1_dma_unmap *unmap)
 379{
 380        long ret = 0, npage = unmap->size >> PAGE_SHIFT;
 381        struct vfio_dma *dma, *tmp;
 382        uint64_t mask;
 383
 384        mask = ((uint64_t)1 << __ffs(iommu->domain->ops->pgsize_bitmap)) - 1;
 385
 386        if (unmap->iova & mask)
 387                return -EINVAL;
 388        if (unmap->size & mask)
 389                return -EINVAL;
 390
 391        /* XXX We still break these down into PAGE_SIZE */
 392        WARN_ON(mask & PAGE_MASK);
 393
 394        mutex_lock(&iommu->lock);
 395
 396        list_for_each_entry_safe(dma, tmp, &iommu->dma_list, next) {
 397                if (ranges_overlap(dma->iova, NPAGE_TO_SIZE(dma->npage),
 398                                   unmap->iova, unmap->size)) {
 399                        ret = vfio_remove_dma_overlap(iommu, unmap->iova,
 400                                                      unmap->size, dma);
 401                        if (ret > 0)
 402                                npage -= ret;
 403                        if (ret < 0 || npage == 0)
 404                                break;
 405                }
 406        }
 407        mutex_unlock(&iommu->lock);
 408        return ret > 0 ? 0 : (int)ret;
 409}
 410
 411static int vfio_dma_do_map(struct vfio_iommu *iommu,
 412                           struct vfio_iommu_type1_dma_map *map)
 413{
 414        struct vfio_dma *dma, *pdma = NULL;
 415        dma_addr_t iova = map->iova;
 416        unsigned long locked, lock_limit, vaddr = map->vaddr;
 417        size_t size = map->size;
 418        int ret = 0, prot = 0;
 419        uint64_t mask;
 420        long npage;
 421
 422        mask = ((uint64_t)1 << __ffs(iommu->domain->ops->pgsize_bitmap)) - 1;
 423
 424        /* READ/WRITE from device perspective */
 425        if (map->flags & VFIO_DMA_MAP_FLAG_WRITE)
 426                prot |= IOMMU_WRITE;
 427        if (map->flags & VFIO_DMA_MAP_FLAG_READ)
 428                prot |= IOMMU_READ;
 429
 430        if (!prot)
 431                return -EINVAL; /* No READ/WRITE? */
 432
 433        if (vaddr & mask)
 434                return -EINVAL;
 435        if (iova & mask)
 436                return -EINVAL;
 437        if (size & mask)
 438                return -EINVAL;
 439
 440        /* XXX We still break these down into PAGE_SIZE */
 441        WARN_ON(mask & PAGE_MASK);
 442
 443        /* Don't allow IOVA wrap */
 444        if (iova + size && iova + size < iova)
 445                return -EINVAL;
 446
 447        /* Don't allow virtual address wrap */
 448        if (vaddr + size && vaddr + size < vaddr)
 449                return -EINVAL;
 450
 451        npage = size >> PAGE_SHIFT;
 452        if (!npage)
 453                return -EINVAL;
 454
 455        mutex_lock(&iommu->lock);
 456
 457        if (vfio_find_dma(iommu, iova, size)) {
 458                ret = -EBUSY;
 459                goto out_lock;
 460        }
 461
 462        /* account for locked pages */
 463        locked = current->mm->locked_vm + npage;
 464        lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
 465        if (locked > lock_limit && !capable(CAP_IPC_LOCK)) {
 466                pr_warn("%s: RLIMIT_MEMLOCK (%ld) exceeded\n",
 467                        __func__, rlimit(RLIMIT_MEMLOCK));
 468                ret = -ENOMEM;
 469                goto out_lock;
 470        }
 471
 472        ret = __vfio_dma_map(iommu, iova, vaddr, npage, prot);
 473        if (ret)
 474                goto out_lock;
 475
 476        /* Check if we abut a region below - nothing below 0 */
 477        if (iova) {
 478                dma = vfio_find_dma(iommu, iova - 1, 1);
 479                if (dma && dma->prot == prot &&
 480                    dma->vaddr + NPAGE_TO_SIZE(dma->npage) == vaddr) {
 481
 482                        dma->npage += npage;
 483                        iova = dma->iova;
 484                        vaddr = dma->vaddr;
 485                        npage = dma->npage;
 486                        size = NPAGE_TO_SIZE(npage);
 487
 488                        pdma = dma;
 489                }
 490        }
 491
 492        /* Check if we abut a region above - nothing above ~0 + 1 */
 493        if (iova + size) {
 494                dma = vfio_find_dma(iommu, iova + size, 1);
 495                if (dma && dma->prot == prot &&
 496                    dma->vaddr == vaddr + size) {
 497
 498                        dma->npage += npage;
 499                        dma->iova = iova;
 500                        dma->vaddr = vaddr;
 501
 502                        /*
 503                         * If merged above and below, remove previously
 504                         * merged entry.  New entry covers it.
 505                         */
 506                        if (pdma) {
 507                                list_del(&pdma->next);
 508                                kfree(pdma);
 509                        }
 510                        pdma = dma;
 511                }
 512        }
 513
 514        /* Isolated, new region */
 515        if (!pdma) {
 516                dma = kzalloc(sizeof *dma, GFP_KERNEL);
 517                if (!dma) {
 518                        ret = -ENOMEM;
 519                        vfio_dma_unmap(iommu, iova, npage, prot);
 520                        goto out_lock;
 521                }
 522
 523                dma->npage = npage;
 524                dma->iova = iova;
 525                dma->vaddr = vaddr;
 526                dma->prot = prot;
 527                list_add(&dma->next, &iommu->dma_list);
 528        }
 529
 530out_lock:
 531        mutex_unlock(&iommu->lock);
 532        return ret;
 533}
 534
 535static int vfio_iommu_type1_attach_group(void *iommu_data,
 536                                         struct iommu_group *iommu_group)
 537{
 538        struct vfio_iommu *iommu = iommu_data;
 539        struct vfio_group *group, *tmp;
 540        int ret;
 541
 542        group = kzalloc(sizeof(*group), GFP_KERNEL);
 543        if (!group)
 544                return -ENOMEM;
 545
 546        mutex_lock(&iommu->lock);
 547
 548        list_for_each_entry(tmp, &iommu->group_list, next) {
 549                if (tmp->iommu_group == iommu_group) {
 550                        mutex_unlock(&iommu->lock);
 551                        kfree(group);
 552                        return -EINVAL;
 553                }
 554        }
 555
 556        /*
 557         * TODO: Domain have capabilities that might change as we add
 558         * groups (see iommu->cache, currently never set).  Check for
 559         * them and potentially disallow groups to be attached when it
 560         * would change capabilities (ugh).
 561         */
 562        ret = iommu_attach_group(iommu->domain, iommu_group);
 563        if (ret) {
 564                mutex_unlock(&iommu->lock);
 565                kfree(group);
 566                return ret;
 567        }
 568
 569        group->iommu_group = iommu_group;
 570        list_add(&group->next, &iommu->group_list);
 571
 572        mutex_unlock(&iommu->lock);
 573
 574        return 0;
 575}
 576
 577static void vfio_iommu_type1_detach_group(void *iommu_data,
 578                                          struct iommu_group *iommu_group)
 579{
 580        struct vfio_iommu *iommu = iommu_data;
 581        struct vfio_group *group;
 582
 583        mutex_lock(&iommu->lock);
 584
 585        list_for_each_entry(group, &iommu->group_list, next) {
 586                if (group->iommu_group == iommu_group) {
 587                        iommu_detach_group(iommu->domain, iommu_group);
 588                        list_del(&group->next);
 589                        kfree(group);
 590                        break;
 591                }
 592        }
 593
 594        mutex_unlock(&iommu->lock);
 595}
 596
 597static void *vfio_iommu_type1_open(unsigned long arg)
 598{
 599        struct vfio_iommu *iommu;
 600
 601        if (arg != VFIO_TYPE1_IOMMU)
 602                return ERR_PTR(-EINVAL);
 603
 604        iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
 605        if (!iommu)
 606                return ERR_PTR(-ENOMEM);
 607
 608        INIT_LIST_HEAD(&iommu->group_list);
 609        INIT_LIST_HEAD(&iommu->dma_list);
 610        mutex_init(&iommu->lock);
 611
 612        /*
 613         * Wish we didn't have to know about bus_type here.
 614         */
 615        iommu->domain = iommu_domain_alloc(&pci_bus_type);
 616        if (!iommu->domain) {
 617                kfree(iommu);
 618                return ERR_PTR(-EIO);
 619        }
 620
 621        /*
 622         * Wish we could specify required capabilities rather than create
 623         * a domain, see what comes out and hope it doesn't change along
 624         * the way.  Fortunately we know interrupt remapping is global for
 625         * our iommus.
 626         */
 627        if (!allow_unsafe_interrupts &&
 628            !iommu_domain_has_cap(iommu->domain, IOMMU_CAP_INTR_REMAP)) {
 629                pr_warn("%s: No interrupt remapping support.  Use the module param \"allow_unsafe_interrupts\" to enable VFIO IOMMU support on this platform\n",
 630                       __func__);
 631                iommu_domain_free(iommu->domain);
 632                kfree(iommu);
 633                return ERR_PTR(-EPERM);
 634        }
 635
 636        return iommu;
 637}
 638
 639static void vfio_iommu_type1_release(void *iommu_data)
 640{
 641        struct vfio_iommu *iommu = iommu_data;
 642        struct vfio_group *group, *group_tmp;
 643        struct vfio_dma *dma, *dma_tmp;
 644
 645        list_for_each_entry_safe(group, group_tmp, &iommu->group_list, next) {
 646                iommu_detach_group(iommu->domain, group->iommu_group);
 647                list_del(&group->next);
 648                kfree(group);
 649        }
 650
 651        list_for_each_entry_safe(dma, dma_tmp, &iommu->dma_list, next) {
 652                vfio_dma_unmap(iommu, dma->iova, dma->npage, dma->prot);
 653                list_del(&dma->next);
 654                kfree(dma);
 655        }
 656
 657        iommu_domain_free(iommu->domain);
 658        iommu->domain = NULL;
 659        kfree(iommu);
 660}
 661
 662static long vfio_iommu_type1_ioctl(void *iommu_data,
 663                                   unsigned int cmd, unsigned long arg)
 664{
 665        struct vfio_iommu *iommu = iommu_data;
 666        unsigned long minsz;
 667
 668        if (cmd == VFIO_CHECK_EXTENSION) {
 669                switch (arg) {
 670                case VFIO_TYPE1_IOMMU:
 671                        return 1;
 672                default:
 673                        return 0;
 674                }
 675        } else if (cmd == VFIO_IOMMU_GET_INFO) {
 676                struct vfio_iommu_type1_info info;
 677
 678                minsz = offsetofend(struct vfio_iommu_type1_info, iova_pgsizes);
 679
 680                if (copy_from_user(&info, (void __user *)arg, minsz))
 681                        return -EFAULT;
 682
 683                if (info.argsz < minsz)
 684                        return -EINVAL;
 685
 686                info.flags = 0;
 687
 688                info.iova_pgsizes = iommu->domain->ops->pgsize_bitmap;
 689
 690                return copy_to_user((void __user *)arg, &info, minsz);
 691
 692        } else if (cmd == VFIO_IOMMU_MAP_DMA) {
 693                struct vfio_iommu_type1_dma_map map;
 694                uint32_t mask = VFIO_DMA_MAP_FLAG_READ |
 695                                VFIO_DMA_MAP_FLAG_WRITE;
 696
 697                minsz = offsetofend(struct vfio_iommu_type1_dma_map, size);
 698
 699                if (copy_from_user(&map, (void __user *)arg, minsz))
 700                        return -EFAULT;
 701
 702                if (map.argsz < minsz || map.flags & ~mask)
 703                        return -EINVAL;
 704
 705                return vfio_dma_do_map(iommu, &map);
 706
 707        } else if (cmd == VFIO_IOMMU_UNMAP_DMA) {
 708                struct vfio_iommu_type1_dma_unmap unmap;
 709
 710                minsz = offsetofend(struct vfio_iommu_type1_dma_unmap, size);
 711
 712                if (copy_from_user(&unmap, (void __user *)arg, minsz))
 713                        return -EFAULT;
 714
 715                if (unmap.argsz < minsz || unmap.flags)
 716                        return -EINVAL;
 717
 718                return vfio_dma_do_unmap(iommu, &unmap);
 719        }
 720
 721        return -ENOTTY;
 722}
 723
 724static const struct vfio_iommu_driver_ops vfio_iommu_driver_ops_type1 = {
 725        .name           = "vfio-iommu-type1",
 726        .owner          = THIS_MODULE,
 727        .open           = vfio_iommu_type1_open,
 728        .release        = vfio_iommu_type1_release,
 729        .ioctl          = vfio_iommu_type1_ioctl,
 730        .attach_group   = vfio_iommu_type1_attach_group,
 731        .detach_group   = vfio_iommu_type1_detach_group,
 732};
 733
 734static int __init vfio_iommu_type1_init(void)
 735{
 736        if (!iommu_present(&pci_bus_type))
 737                return -ENODEV;
 738
 739        return vfio_register_iommu_driver(&vfio_iommu_driver_ops_type1);
 740}
 741
 742static void __exit vfio_iommu_type1_cleanup(void)
 743{
 744        vfio_unregister_iommu_driver(&vfio_iommu_driver_ops_type1);
 745}
 746
 747module_init(vfio_iommu_type1_init);
 748module_exit(vfio_iommu_type1_cleanup);
 749
 750MODULE_VERSION(DRIVER_VERSION);
 751MODULE_LICENSE("GPL v2");
 752MODULE_AUTHOR(DRIVER_AUTHOR);
 753MODULE_DESCRIPTION(DRIVER_DESC);
 754
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.