27 Jul, 2016

1 commit


15 Feb, 2016

1 commit

  • According to the VT-d specification we need to clear the PPR bit in
    the Page Request Status register when handling page requests, or the
    hardware won't generate any more interrupts.

    This wasn't actually necessary on SKL/KBL (which may well be the
    subject of a hardware erratum, although it's harmless enough). But
    other implementations do appear to get it right, and we only ever get
    one interrupt unless we clear the PPR bit.

    Reported-by: CQ Tang
    Signed-off-by: David Woodhouse
    Cc: stable@vger.kernel.org

    David Woodhouse
     

14 Jan, 2016

1 commit

  • Holding mm_users works OK for graphics, which was the first user of SVM
    with VT-d. However, it works less well for other devices, where we actually
    do a mmap() from the file descriptor to which the SVM PASID state is tied.

    In this case on process exit we end up with a recursive reference count:
    - The MM remains alive until the file is closed and the driver's release()
    call ends up unbinding the PASID.
    - The VMA corresponding to the mmap() remains intact until the MM is
    destroyed.
    - Thus the file isn't closed, even when exit_files() runs, because the
    VMA is still holding a reference to it. And the MM remains alive…

    To address this issue, we *stop* holding mm_users while the PASID is bound.
    We already hold mm_count by virtue of the MMU notifier, and that can be
    made to be sufficient.

    It means that for a period during process exit, the fun part of mmput()
    has happened and exit_mmap() has been called so the MM is basically
    defunct. But the PGD still exists and the PASID is still bound to it.

    During this period, we have to be very careful — exit_mmap() doesn't use
    mm->mmap_sem because it doesn't expect anyone else to be touching the MM
    (quite reasonably, since mm_users is zero). So we also need to fix the
    fault handler to just report failure if mm_users is already zero, and to
    temporarily bump mm_users while handling any faults.

    Additionally, exit_mmap() calls mmu_notifier_release() *before* it tears
    down the page tables, which is too early for us to flush the IOTLB for
    this PASID. And __mmu_notifier_release() removes every notifier from the
    list, so when exit_mmap() finally *does* tear down the mappings and
    clear the page tables, we don't get notified. So we work around this by
    clearing the PASID table entry in our MMU notifier release() callback.
    That way, the hardware *can't* get any pages back from the page tables
    before they get cleared.

    Hardware designers have confirmed that the resulting 'PASID not present'
    faults should be handled just as gracefully as 'page not present' faults,
    the important criterion being that they don't perturb the operation for
    any *other* PASID in the system.

    Signed-off-by: David Woodhouse
    Cc: stable@vger.kernel.org

    David Woodhouse
     

14 Dec, 2015

1 commit


28 Oct, 2015

1 commit


25 Oct, 2015

1 commit


20 Oct, 2015

1 commit

  • Change the 'pages' parameter to 'unsigned long' to avoid overflow.

    Fix the device-IOTLB flush parameter calculation — the size of the IOTLB
    flush is indicated by the position of the least significant zero bit in
    the address field. For example, a value of 0x12345f000 will flush from
    0x123440000 to 0x12347ffff (256KiB).

    Finally, the cap_pgsel_inv() is not relevant to SVM; the spec says that
    *all* implementations must support page-selective invaliation for
    "first-level" translations. So don't check for it.

    Signed-off-by: David Woodhouse

    David Woodhouse
     

18 Oct, 2015

1 commit


17 Oct, 2015

2 commits


16 Oct, 2015

2 commits


15 Oct, 2015

7 commits