mbox series

[00/16] KVM: arm64: Implement unshare hypercall for pkvm

Message ID 20211013155831.943476-1-qperret@google.com (mailing list archive)
Headers show
Series KVM: arm64: Implement unshare hypercall for pkvm | expand

Message

Quentin Perret Oct. 13, 2021, 3:58 p.m. UTC
Hi all,

This series implements an unshare hypercall at EL2 in nVHE protected
mode, and makes use of it to unmmap guest-specific data-structures from
EL2 stage-1 during guest tear-down. Crucially, the implementation of the
share and unshare hypercall implements page refcounts at EL2 to avoid
accidentally unmapping data-structures that overlap a common page.

This series has two main benefits. Firstly it allows EL2 to track the
state of shared pages cleanly, as they can now transition from SHARED
back to OWNED. This will simplify permission checks once e.g. pkvm
implements a donation hcall to provide memory to protected guests, as
there should then be no reason for the host to donate a page that is
currently marked shared. And secondly, it avoids having dangling
mappings in the hypervisor's stage-1, which should be a good idea from
a security perspective as the hypervisor is obviously running with
elevated privileges. And perhaps worth noting is that this also
refactors the EL2 page-tracking checks in a more scalable way, which
should allow to implement other memory transitions (host donating memory
to a guest, a guest sharing back with the host, ...) much more easily in
the future.

The series is organized as follows:

 - patches 01-05 refactor the implementation of the existing share
   hypercall;

 - patches 06-10 introduce infrastructure to allow unmapping pages from
   EL2 stage-1;

 - patches 11-14 allow to refcount pages that are shared more than once
   with EL2;

 - patches 15-16 add the unshare hypercall, and make use of it when
   tearing down guests.

This has been lightly tested on Qemu, by spawning and powering off a
guest 50 times.

Feedback welcome :) !

Thanks,
Quentin

Quentin Perret (11):
  KVM: arm64: Avoid remapping the SVE state in the hyp stage-1
  KVM: arm64: Introduce kvm_share_hyp()
  KVM: arm64: Accept page ranges in pkvm share hypercall
  KVM: arm64: Provide {get,put}_page() stubs for early hyp allocator
  KVM: arm64: Refcount hyp stage-1 pgtable pages
  KVM: arm64: Fixup hyp stage-1 refcount
  KVM: arm64: Back hyp_vmemmap for all of memory
  KVM: arm64: Move hyp refcount helpers to header files
  KVM: arm64: Refcount shared pages at EL2
  KVM: arm64: pkvm: Introduce an unshare hypercall
  KVM: arm64: pkvm: Unshare guest structs during teardown

Will Deacon (5):
  KVM: arm64: Introduce do_share() helper for memory sharing between
    components
  KVM: arm64: Implement __pkvm_host_share_hyp() using do_share()
  KVM: arm64: Hook up ->page_count() for hypervisor stage-1 page-table
  KVM: arm64: Implement kvm_pgtable_hyp_unmap() at EL2
  KVM: arm64: Move double-sharing logic into hyp-specific function

 arch/arm64/include/asm/kvm_asm.h              |   1 +
 arch/arm64/include/asm/kvm_host.h             |   2 +
 arch/arm64/include/asm/kvm_mmu.h              |   2 +
 arch/arm64/include/asm/kvm_pgtable.h          |  21 +
 arch/arm64/kvm/arm.c                          |  17 +-
 arch/arm64/kvm/fpsimd.c                       |  25 +-
 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |   8 +-
 arch/arm64/kvm/hyp/include/nvhe/memory.h      |  18 +
 arch/arm64/kvm/hyp/include/nvhe/mm.h          |  29 +-
 arch/arm64/kvm/hyp/nvhe/early_alloc.c         |   5 +
 arch/arm64/kvm/hyp/nvhe/hyp-main.c            |  12 +-
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 596 ++++++++++++++++--
 arch/arm64/kvm/hyp/nvhe/mm.c                  |  31 +-
 arch/arm64/kvm/hyp/nvhe/page_alloc.c          |  22 +-
 arch/arm64/kvm/hyp/nvhe/setup.c               |  39 +-
 arch/arm64/kvm/hyp/pgtable.c                  |  80 ++-
 arch/arm64/kvm/hyp/reserved_mem.c             |  17 +-
 arch/arm64/kvm/mmu.c                          |  48 +-
 arch/arm64/kvm/reset.c                        |  13 +-
 19 files changed, 814 insertions(+), 172 deletions(-)