Skip to content
Permalink
Quentin-Perret…
Switch branches/tags

Commits on Mar 19, 2021

  1. KVM: arm64: Protect the .hyp sections from the host

    When KVM runs in nVHE protected mode, use the host stage 2 to unmap the
    hypervisor sections by marking them as owned by the hypervisor itself.
    The long-term goal is to ensure the EL2 code can remain robust
    regardless of the host's state, so this starts by making sure the host
    cannot e.g. write to the .hyp sections directly.
    
    Acked-by: Will Deacon <will@kernel.org>
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
  2. KVM: arm64: Disable PMU support in protected mode

    The host currently writes directly in EL2 per-CPU data sections from
    the PMU code when running in nVHE. In preparation for unmapping the EL2
    sections from the host stage 2, disable PMU support in protected mode as
    we currently do not have a use-case for it.
    
    Acked-by: Will Deacon <will@kernel.org>
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
  3. KVM: arm64: Page-align the .hyp sections

    We will soon unmap the .hyp sections from the host stage 2 in Protected
    nVHE mode, which obviously works with at least page granularity, so make
    sure to align them correctly.
    
    Acked-by: Will Deacon <will@kernel.org>
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
  4. KVM: arm64: Wrap the host with a stage 2

    When KVM runs in protected nVHE mode, make use of a stage 2 page-table
    to give the hypervisor some control over the host memory accesses. The
    host stage 2 is created lazily using large block mappings if possible,
    and will default to page mappings in absence of a better solution.
    
    From this point on, memory accesses from the host to protected memory
    regions (e.g. not 'owned' by the host) are fatal and lead to hyp_panic().
    
    Acked-by: Will Deacon <will@kernel.org>
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
  5. KVM: arm64: Provide sanitized mmfr* registers at EL2

    We will need to read sanitized values of mmfr{0,1}_el1 at EL2 soon, so
    add them to the list of copied variables.
    
    Acked-by: Will Deacon <will@kernel.org>
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
  6. KVM: arm64: Introduce KVM_PGTABLE_S2_IDMAP stage 2 flag

    Introduce a new stage 2 configuration flag to specify that all mappings
    in a given page-table will be identity-mapped, as will be the case for
    the host. This allows to introduce sanity checks in the map path and to
    avoid programming errors.
    
    Suggested-by: Will Deacon <will@kernel.org>
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
  7. KVM: arm64: Introduce KVM_PGTABLE_S2_NOFWB stage 2 flag

    In order to further configure stage 2 page-tables, pass flags to the
    init function using a new enum.
    
    The first of these flags allows to disable FWB even if the hardware
    supports it as we will need to do so for the host stage 2.
    
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
  8. KVM: arm64: Add kvm_pgtable_stage2_find_range()

    Since the host stage 2 will be identity mapped, and since it will own
    most of memory, it would preferable for performance to try and use large
    block mappings whenever that is possible. To ease this, introduce a new
    helper in the KVM page-table code which allows to search for large
    ranges of available IPA space. This will be used in the host memory
    abort path to greedily idmap large portion of the PA space.
    
    Acked-by: Will Deacon <will@kernel.org>
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
  9. KVM: arm64: Refactor the *_map_set_prot_attr() helpers

    In order to ease their re-use in other code paths, refactor the
    *_map_set_prot_attr() helpers to not depend on a map_data struct.
    No functional change intended.
    
    Acked-by: Will Deacon <will@kernel.org>
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
  10. KVM: arm64: Use page-table to track page ownership

    As the host stage 2 will be identity mapped, all the .hyp memory regions
    and/or memory pages donated to protected guestis will have to marked
    invalid in the host stage 2 page-table. At the same time, the hypervisor
    will need a way to track the ownership of each physical page to ensure
    memory sharing or donation between entities (host, guests, hypervisor) is
    legal.
    
    In order to enable this tracking at EL2, let's use the host stage 2
    page-table itself. The idea is to use the top bits of invalid mappings
    to store the unique identifier of the page owner. The page-table owner
    (the host) gets identifier 0 such that, at boot time, it owns the entire
    IPA space as the pgd starts zeroed.
    
    Provide kvm_pgtable_stage2_set_owner() which allows to modify the
    ownership of pages in the host stage 2. It re-uses most of the map()
    logic, but ends up creating invalid mappings instead. This impacts
    how we do refcount as we now need to count invalid mappings when they
    are used for ownership tracking.
    
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
  11. KVM: arm64: Always zero invalid PTEs

    kvm_set_invalid_pte() currently only clears bit 0 from a PTE because
    stage2_map_walk_table_post() needs to be able to follow the anchor. In
    preparation for re-using bits 63-01 from invalid PTEs, make sure to zero
    it entirely by ensuring to cache the anchor's child upfront.
    
    Acked-by: Will Deacon <will@kernel.org>
    Suggested-by: Will Deacon <will@kernel.org>
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
  12. KVM: arm64: Sort the hypervisor memblocks

    We will soon need to check if a Physical Address belongs to a memblock
    at EL2, so make sure to sort them so this can be done efficiently.
    
    Acked-by: Will Deacon <will@kernel.org>
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
  13. KVM: arm64: Reserve memory for host stage 2

    Extend the memory pool allocated for the hypervisor to include enough
    pages to map all of memory at page granularity for the host stage 2.
    While at it, also reserve some memory for device mappings.
    
    Acked-by: Will Deacon <will@kernel.org>
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
  14. KVM: arm64: Make memcache anonymous in pgtable allocator

    The current stage2 page-table allocator uses a memcache to get
    pre-allocated pages when it needs any. To allow re-using this code at
    EL2 which uses a concept of memory pools, make the memcache argument of
    kvm_pgtable_stage2_map() anonymous, and let the mm_ops zalloc_page()
    callbacks use it the way they need to.
    
    Acked-by: Will Deacon <will@kernel.org>
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
  15. KVM: arm64: Refactor __populate_fault_info()

    Refactor __populate_fault_info() to introduce __get_fault_info() which
    will be used once the host is wrapped in a stage 2.
    
    Acked-by: Will Deacon <will@kernel.org>
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
  16. KVM: arm64: Refactor __load_guest_stage2()

    Refactor __load_guest_stage2() to introduce __load_stage2() which will
    be re-used when loading the host stage 2.
    
    Acked-by: Will Deacon <will@kernel.org>
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
  17. KVM: arm64: Refactor kvm_arm_setup_stage2()

    In order to re-use some of the stage 2 setup code at EL2, factor parts
    of kvm_arm_setup_stage2() out into separate functions.
    
    No functional change intended.
    
    Acked-by: Will Deacon <will@kernel.org>
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
  18. KVM: arm64: Set host stage 2 using kvm_nvhe_init_params

    Move the registers relevant to host stage 2 enablement to
    kvm_nvhe_init_params to prepare the ground for enabling it in later
    patches.
    
    Acked-by: Will Deacon <will@kernel.org>
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
  19. KVM: arm64: Use kvm_arch in kvm_s2_mmu

    In order to make use of the stage 2 pgtable code for the host stage 2,
    change kvm_s2_mmu to use a kvm_arch pointer in lieu of the kvm pointer,
    as the host will have the former but not the latter.
    
    Acked-by: Will Deacon <will@kernel.org>
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
  20. KVM: arm64: Use kvm_arch for stage 2 pgtable

    In order to make use of the stage 2 pgtable code for the host stage 2,
    use struct kvm_arch in lieu of struct kvm as the host will have the
    former but not the latter.
    
    Acked-by: Will Deacon <will@kernel.org>
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
  21. KVM: arm64: Elevate hypervisor mappings creation at EL2

    Previous commits have introduced infrastructure to enable the EL2 code
    to manage its own stage 1 mappings. However, this was preliminary work,
    and none of it is currently in use.
    
    Put all of this together by elevating the mapping creation at EL2 when
    memory protection is enabled. In this case, the host kernel running
    at EL1 still creates _temporary_ EL2 mappings, only used while
    initializing the hypervisor, but frees them right after.
    
    As such, all calls to create_hyp_mappings() after kvm init has finished
    turn into hypercalls, as the host now has no 'legal' way to modify the
    hypevisor page tables directly.
    
    Acked-by: Will Deacon <will@kernel.org>
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
  22. KVM: arm64: Prepare the creation of s1 mappings at EL2

    When memory protection is enabled, the EL2 code needs the ability to
    create and manage its own page-table. To do so, introduce a new set of
    hypercalls to bootstrap a memory management system at EL2.
    
    This leads to the following boot flow in nVHE Protected mode:
    
     1. the host allocates memory for the hypervisor very early on, using
        the memblock API;
    
     2. the host creates a set of stage 1 page-table for EL2, installs the
        EL2 vectors, and issues the __pkvm_init hypercall;
    
     3. during __pkvm_init, the hypervisor re-creates its stage 1 page-table
        and stores it in the memory pool provided by the host;
    
     4. the hypervisor then extends its stage 1 mappings to include a
        vmemmap in the EL2 VA space, hence allowing to use the buddy
        allocator introduced in a previous patch;
    
     5. the hypervisor jumps back in the idmap page, switches from the
        host-provided page-table to the new one, and wraps up its
        initialization by enabling the new allocator, before returning to
        the host.
    
     6. the host can free the now unused page-table created for EL2, and
        will now need to issue hypercalls to make changes to the EL2 stage 1
        mappings instead of modifying them directly.
    
    Note that for the sake of simplifying the review, this patch focuses on
    the hypervisor side of things. In other words, this only implements the
    new hypercalls, but does not make use of them from the host yet. The
    host-side changes will follow in a subsequent patch.
    
    Credits to Will for __pkvm_init_switch_pgd.
    
    Acked-by: Will Deacon <will@kernel.org>
    Co-authored-by: Will Deacon <will@kernel.org>
    Signed-off-by: Will Deacon <will@kernel.org>
    Signed-off-by: Quentin Perret <qperret@google.com>
    2 people authored and intel-lab-lkp committed Mar 19, 2021
  23. arm64: asm: Provide set_sctlr_el2 macro

    We will soon need to turn the EL2 stage 1 MMU on and off in nVHE
    protected mode, so refactor the set_sctlr_el1 macro to make it usable
    for that purpose.
    
    Acked-by: Will Deacon <will@kernel.org>
    Suggested-by: Will Deacon <will@kernel.org>
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
  24. KVM: arm64: Factor out vector address calculation

    In order to re-map the guest vectors at EL2 when pKVM is enabled,
    refactor __kvm_vector_slot2idx() and kvm_init_vector_slot() to move all
    the address calculation logic in a static inline function.
    
    Acked-by: Will Deacon <will@kernel.org>
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
  25. KVM: arm64: Provide __flush_dcache_area at EL2

    We will need to do cache maintenance at EL2 soon, so compile a copy of
    __flush_dcache_area at EL2, and provide a copy of arm64_ftr_reg_ctrel0
    as it is needed by the read_ctr macro.
    
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
  26. KVM: arm64: Enable access to sanitized CPU features at EL2

    Introduce the infrastructure in KVM enabling to copy CPU feature
    registers into EL2-owned data-structures, to allow reading sanitised
    values directly at EL2 in nVHE.
    
    Given that only a subset of these features are being read by the
    hypervisor, the ones that need to be copied are to be listed under
    <asm/kvm_cpufeature.h> together with the name of the nVHE variable that
    will hold the copy. This introduces only the infrastructure enabling
    this copy. The first users will follow shortly.
    
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
  27. KVM: arm64: Introduce a Hyp buddy page allocator

    When memory protection is enabled, the hyp code will require a basic
    form of memory management in order to allocate and free memory pages at
    EL2. This is needed for various use-cases, including the creation of hyp
    mappings or the allocation of stage 2 page tables.
    
    To address these use-case, introduce a simple memory allocator in the
    hyp code. The allocator is designed as a conventional 'buddy allocator',
    working with a page granularity. It allows to allocate and free
    physically contiguous pages from memory 'pools', with a guaranteed order
    alignment in the PA space. Each page in a memory pool is associated
    with a struct hyp_page which holds the page's metadata, including its
    refcount, as well as its current order, hence mimicking the kernel's
    buddy system in the GFP infrastructure. The hyp_page metadata are made
    accessible through a hyp_vmemmap, following the concept of
    SPARSE_VMEMMAP in the kernel.
    
    Acked-by: Will Deacon <will@kernel.org>
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
  28. KVM: arm64: Stub CONFIG_DEBUG_LIST at Hyp

    In order to use the kernel list library at EL2, introduce stubs for the
    CONFIG_DEBUG_LIST out-of-lines calls.
    
    Acked-by: Will Deacon <will@kernel.org>
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
  29. KVM: arm64: Introduce an early Hyp page allocator

    With nVHE, the host currently creates all stage 1 hypervisor mappings at
    EL1 during boot, installs them at EL2, and extends them as required
    (e.g. when creating a new VM). But in a world where the host is no
    longer trusted, it cannot have full control over the code mapped in the
    hypervisor.
    
    In preparation for enabling the hypervisor to create its own stage 1
    mappings during boot, introduce an early page allocator, with minimal
    functionality. This allocator is designed to be used only during early
    bootstrap of the hyp code when memory protection is enabled, which will
    then switch to using a full-fledged page allocator after init.
    
    Acked-by: Will Deacon <will@kernel.org>
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
  30. KVM: arm64: Allow using kvm_nvhe_sym() in hyp code

    In order to allow the usage of code shared by the host and the hyp in
    static inline library functions, allow the usage of kvm_nvhe_sym() at
    EL2 by defaulting to the raw symbol name.
    
    Acked-by: Will Deacon <will@kernel.org>
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
  31. KVM: arm64: Make kvm_call_hyp() a function call at Hyp

    kvm_call_hyp() has some logic to issue a function call or a hypercall
    depending on the EL at which the kernel is running. However, all the
    code compiled under __KVM_NVHE_HYPERVISOR__ is guaranteed to only run
    at EL2 which allows us to simplify.
    
    Add ifdefery to kvm_host.h to simplify kvm_call_hyp() in .hyp.text.
    
    Acked-by: Will Deacon <will@kernel.org>
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
  32. KVM: arm64: Introduce a BSS section for use at Hyp

    Currently, the hyp code cannot make full use of a bss, as the kernel
    section is mapped read-only.
    
    While this mapping could simply be changed to read-write, it would
    intermingle even more the hyp and kernel state than they currently are.
    Instead, introduce a __hyp_bss section, that uses reserved pages, and
    create the appropriate RW hyp mappings during KVM init.
    
    Acked-by: Will Deacon <will@kernel.org>
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
  33. KVM: arm64: Factor memory allocation out of pgtable.c

    In preparation for enabling the creation of page-tables at EL2, factor
    all memory allocation out of the page-table code, hence making it
    re-usable with any compatible memory allocator.
    
    No functional changes intended.
    
    Acked-by: Will Deacon <will@kernel.org>
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
  34. KVM: arm64: Avoid free_page() in page-table allocator

    Currently, the KVM page-table allocator uses a mix of put_page() and
    free_page() calls depending on the context even though page-allocation
    is always achieved using variants of __get_free_page().
    
    Make the code consistent by using put_page() throughout, and reduce the
    memory management API surface used by the page-table code. This will
    ease factoring out page-allocation from pgtable.c, which is a
    pre-requisite to creating page-tables at EL2.
    
    Acked-by: Will Deacon <will@kernel.org>
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
  35. KVM: arm64: Initialize kvm_nvhe_init_params early

    Move the initialization of kvm_nvhe_init_params in a dedicated function
    that is run early, and only once during KVM init, rather than every time
    the KVM vectors are set and reset.
    
    This also opens the opportunity for the hypervisor to change the init
    structs during boot, hence simplifying the replacement of host-provided
    page-table by the one the hypervisor will create for itself.
    
    Acked-by: Will Deacon <will@kernel.org>
    Signed-off-by: Quentin Perret <qperret@google.com>
    Quentin Perret authored and intel-lab-lkp committed Mar 19, 2021
Older