[PATCH 00/20] KVM: arm64: Rewrite page-table code and fault handling

Will Deacon will at kernel.org
Thu Jul 30 11:33:46 EDT 2020


Hi all,

This fairly hefty series rewrites all of KVM's page-table code on arm64.

You might be wondering why I've done that, and I can ensure you that it
wasn't for fun. No, some of the benefits of rewriting this code are as
follows:

  * The hypervisor stage-1 and guest stage-2 page tables can now be
    configured at runtime, independently of each other and of the host
    kernel's stage-1 configuration. This allows us to remove the extended
    idmap at EL2 entirely and accept large guest IPA sizes without
    worrying about the number of levels in use by the host.

  * The code is smaller. We're losing ~500 lines with this series, and
    that's in spite of a bunch of kerneldoc being added for the new API.

  * It paves the way for managing the stage-2 page-tables at EL2 on nVHE
    systems, which is a crucial part of the Android "Protected KVM" project,
    which aims to isolate guest memory from the host kernel.

  * In some cases, the new walker allows us to reduce the number of walks
    being performed. For example, user_mem_abort() no longer has to walk
    the page-table twice when handling permission faults.

The series is based on kvmarm/next, plus these two series I sent previously:

  - memcache cleanups:
  https://lore.kernel.org/r/20200723110227.16001-1-will@kernel.org

  - Early S2 fault fixes:
  https://lore.kernel.org/r/20200729102821.23392-1-will@kernel.org

It will conflict with Sean's memcache stuff in -next, but that shouldn't
be too hard to sort out.

I've tried to split up the conversion of kvm/mmu.c into reviewable chunks,
mopping up all the leftover code at the end. That means bisection will
warn about unused functions in the middle of the series, but I think it
makes the changes considerably more focussed and easier to review.

In terms of testing, I've done the usual Debian installer type things, but
Quentin has also written targetted guest code [1] which we used to
exercise dirty logging page-table collapse and coalescing. I also wrote a
silly hack where KVM allocated two S2 page-tables for each VM; one using
the old code and one using the new code. At PSCI SYSTEM_OFF, a walker
walked each page-table, using siphash to create a hash of all of the
entries (but masking out the address fields in table entries). After the
walk, the hashes were compared for the two tables and I have so far been
unable to trigger a mismatch. That said, I haven't really kicked the tyres
outside of defconfig.

To make things easier to work with, I've put the whole lot on a branch
here:

  https://android-kvm.googlesource.com/linux/+/refs/heads/topic/pgtable

Cheers,

Will

[1] https://android-kvm.googlesource.com/misc/+/refs/heads/qperret/pgtable-test

Cc: Marc Zyngier <maz at kernel.org>
Cc: Quentin Perret <qperret at google.com>
Cc: James Morse <james.morse at arm.com>
Cc: Suzuki Poulose <suzuki.poulose at arm.com>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: kernel-team at android.com
Cc: linux-arm-kernel at lists.infradead.org

--->8

Quentin Perret (4):
  KVM: arm64: Add support for stage-2 write-protect in generic
    page-table
  KVM: arm64: Convert write-protect operation to generic page-table API
  KVM: arm64: Add support for stage-2 cache flushing in generic
    page-table
  KVM: arm64: Convert memslot cache-flushing code to generic page-table
    API

Will Deacon (16):
  KVM: arm64: Add stand-alone page-table walker infrastructure
  KVM: arm64: Add support for creating kernel-agnostic stage-1 page
    tables
  KVM: arm64: Use generic allocator for hyp stage-1 page-tables
  KVM: arm64: Add support for creating kernel-agnostic stage-2 page
    tables
  KVM: arm64: Add support for stage-2 map()/unmap() in generic
    page-table
  KVM: arm64: Convert kvm_phys_addr_ioremap() to generic page-table API
  KVM: arm64: Convert kvm_set_spte_hva() to generic page-table API
  KVM: arm64: Convert unmap_stage2_range() to generic page-table API
  KVM: arm64: Add support for stage-2 page-aging in generic page-table
  KVM: arm64: Convert page-aging and access faults to generic page-table
    API
  KVM: arm64: Add support for relaxing stage-2 perms in generic
    page-table code
  KVM: arm64: Convert user_mem_abort() to generic page-table API
  KVM: arm64: Check the cookie instead of the pgd when modifying
    page-table
  KVM: arm64: Remove unused page-table code
  KVM: arm64: Remove unused 'pgd' field from 'struct kvm_s2_mmu'
  KVM: arm64: Don't constrain maximum IPA size based on host
    configuration

 arch/arm64/include/asm/kvm_host.h       |    2 +-
 arch/arm64/include/asm/kvm_mmu.h        |  219 +---
 arch/arm64/include/asm/kvm_pgtable.h    |  269 ++++
 arch/arm64/include/asm/pgtable-hwdef.h  |   23 -
 arch/arm64/include/asm/pgtable-prot.h   |   19 -
 arch/arm64/include/asm/stage2_pgtable.h |  215 ----
 arch/arm64/kvm/Makefile                 |    2 +-
 arch/arm64/kvm/mmu.c                    | 1549 +++--------------------
 arch/arm64/kvm/pgtable.c                |  906 +++++++++++++
 arch/arm64/kvm/reset.c                  |   38 +-
 10 files changed, 1340 insertions(+), 1902 deletions(-)
 create mode 100644 arch/arm64/include/asm/kvm_pgtable.h
 create mode 100644 arch/arm64/kvm/pgtable.c

-- 
2.28.0.rc0.142.g3c755180ce-goog




More information about the linux-arm-kernel mailing list