All of lore.kernel.org
 help / color / mirror / Atom feed
From: Fuad Tabba <tabba@google.com>
To: Quentin Perret <qperret@google.com>
Cc: maz@kernel.org, james.morse@arm.com, alexandru.elisei@arm.com,
	suzuki.poulose@arm.com, catalin.marinas@arm.com, will@kernel.org,
	linux-arm-kernel@lists.infradead.org,
	kvmarm@lists.cs.columbia.edu, linux-kernel@vger.kernel.org,
	ardb@kernel.org, qwandor@google.com, dbrazdil@google.com,
	kernel-team@android.com
Subject: Re: [PATCH 13/14] KVM: arm64: Restrict hyp stage-1 manipulation in protected mode
Date: Wed, 21 Jul 2021 11:45:53 +0100	[thread overview]
Message-ID: <CA+EHjTzpoX+rLQHwUbR3BVY_XJEWERiG4AGk7SW6GDtDFC_cuQ@mail.gmail.com> (raw)
In-Reply-To: <20210719104735.3681732-14-qperret@google.com>

Hi Quentin,

On Mon, Jul 19, 2021 at 11:48 AM Quentin Perret <qperret@google.com> wrote:
>
> The host kernel is currently able to change EL2 stage-1 mappings without
> restrictions thanks to the __pkvm_create_mappings() hypercall. But in a
> world where the host is no longer part of the TCB, this clearly poses a
> problem.
>
> To fix this, introduce a new hypercall to allow the host to share a
> range of physical memory with the hypervisor, and remove the
> __pkvm_create_mappings() variant. The new hypercall implements
> ownership and permission checks before allowing the sharing operation,
> and it annotates the shared pages in the hypervisor stage-1 and host
> stage-2 page-tables.
>
> Signed-off-by: Quentin Perret <qperret@google.com>
> ---
>  arch/arm64/include/asm/kvm_asm.h              |   2 +-
>  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |   1 +
>  arch/arm64/kvm/hyp/include/nvhe/mm.h          |   2 -
>  arch/arm64/kvm/hyp/nvhe/hyp-main.c            |  12 +-
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 105 ++++++++++++++++++
>  arch/arm64/kvm/hyp/nvhe/mm.c                  |   4 +-
>  arch/arm64/kvm/mmu.c                          |  14 ++-
>  7 files changed, 124 insertions(+), 16 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> index 9f0bf2109be7..78db818ae2c9 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -59,7 +59,7 @@
>  #define __KVM_HOST_SMCCC_FUNC___vgic_v3_save_aprs              13
>  #define __KVM_HOST_SMCCC_FUNC___vgic_v3_restore_aprs           14
>  #define __KVM_HOST_SMCCC_FUNC___pkvm_init                      15
> -#define __KVM_HOST_SMCCC_FUNC___pkvm_create_mappings           16
> +#define __KVM_HOST_SMCCC_FUNC___pkvm_host_share_hyp            16
>  #define __KVM_HOST_SMCCC_FUNC___pkvm_create_private_mapping    17
>  #define __KVM_HOST_SMCCC_FUNC___pkvm_cpu_set_vector            18
>  #define __KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize             19
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> index b39047463075..f37e4d3b831b 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> @@ -22,6 +22,7 @@ extern struct host_kvm host_kvm;
>
>  int __pkvm_prot_finalize(void);
>  int __pkvm_mark_hyp(phys_addr_t start, phys_addr_t end);
> +int __pkvm_host_share_hyp(phys_addr_t start, phys_addr_t end);
>
>  int host_stage2_idmap_locked(u64 start, u64 end, enum kvm_pgtable_prot prot);
>  int kvm_host_prepare_stage2(void *pgt_pool_base);
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mm.h b/arch/arm64/kvm/hyp/include/nvhe/mm.h
> index c76d7136ed9b..c9a8f535212e 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mm.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mm.h
> @@ -24,8 +24,6 @@ int hyp_back_vmemmap(phys_addr_t phys, unsigned long size, phys_addr_t back);
>  int pkvm_cpu_set_vector(enum arm64_hyp_spectre_vector slot);
>  int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot);
>  int pkvm_create_mappings_locked(void *from, void *to, enum kvm_pgtable_prot prot);
> -int __pkvm_create_mappings(unsigned long start, unsigned long size,
> -                          unsigned long phys, enum kvm_pgtable_prot prot);
>  unsigned long __pkvm_create_private_mapping(phys_addr_t phys, size_t size,
>                                             enum kvm_pgtable_prot prot);
>
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index 1632f001f4ed..f05ecbd382d0 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -140,14 +140,12 @@ static void handle___pkvm_cpu_set_vector(struct kvm_cpu_context *host_ctxt)
>         cpu_reg(host_ctxt, 1) = pkvm_cpu_set_vector(slot);
>  }
>
> -static void handle___pkvm_create_mappings(struct kvm_cpu_context *host_ctxt)
> +static void handle___pkvm_host_share_hyp(struct kvm_cpu_context *host_ctxt)
>  {
> -       DECLARE_REG(unsigned long, start, host_ctxt, 1);
> -       DECLARE_REG(unsigned long, size, host_ctxt, 2);
> -       DECLARE_REG(unsigned long, phys, host_ctxt, 3);
> -       DECLARE_REG(enum kvm_pgtable_prot, prot, host_ctxt, 4);
> +       DECLARE_REG(phys_addr_t, start, host_ctxt, 1);
> +       DECLARE_REG(phys_addr_t, end, host_ctxt, 2);
>
> -       cpu_reg(host_ctxt, 1) = __pkvm_create_mappings(start, size, phys, prot);
> +       cpu_reg(host_ctxt, 1) = __pkvm_host_share_hyp(start, end);
>  }
>
>  static void handle___pkvm_create_private_mapping(struct kvm_cpu_context *host_ctxt)
> @@ -193,7 +191,7 @@ static const hcall_t host_hcall[] = {
>         HANDLE_FUNC(__vgic_v3_restore_aprs),
>         HANDLE_FUNC(__pkvm_init),
>         HANDLE_FUNC(__pkvm_cpu_set_vector),
> -       HANDLE_FUNC(__pkvm_create_mappings),
> +       HANDLE_FUNC(__pkvm_host_share_hyp),
>         HANDLE_FUNC(__pkvm_create_private_mapping),
>         HANDLE_FUNC(__pkvm_prot_finalize),
>         HANDLE_FUNC(__pkvm_mark_hyp),
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index 6f28edf58407..20b3cb3fdc67 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -262,6 +262,111 @@ static int host_stage2_idmap(u64 addr)
>         return ret;
>  }
>
> +static int hyp_range_is_shared_walker(u64 addr, u64 end, u32 level,
> +                                     kvm_pte_t *ptep,
> +                                     enum kvm_pgtable_walk_flags flag,
> +                                     void * const arg)
> +{
> +       enum kvm_pgtable_prot prot;
> +       kvm_pte_t pte = *ptep;
> +
> +       if (!kvm_pte_valid(pte))
> +               return -EPERM;
> +
> +       prot = kvm_pgtable_hyp_pte_prot(pte);
> +       if (!prot)
> +               return -EPERM;
nit: is this check necessary?

> +       /* Check that the page has been shared with the hypervisor before */
> +       if (prot != (PAGE_HYP | KVM_PGTABLE_STATE_SHARED | KVM_PGTABLE_STATE_BORROWED))
> +               return -EPERM;
> +
> +       return 0;
> +}
> +
> +static int hyp_range_is_shared(phys_addr_t start, phys_addr_t end)
> +{
> +       struct kvm_pgtable_walker walker = {
> +               .cb = hyp_range_is_shared_walker,
> +               .flags = KVM_PGTABLE_WALK_LEAF,
> +       };
> +
> +       return kvm_pgtable_walk(&pkvm_pgtable, (u64)__hyp_va(start),
> +                               end - start, &walker);
> +}
> +
> +static int check_host_share_hyp_walker(u64 addr, u64 end, u32 level,

nit: It seems the convention is usually addr,size or start,end. Here
you're using addr,end.

> +                                      kvm_pte_t *ptep,
> +                                      enum kvm_pgtable_walk_flags flag,
> +                                      void * const arg)
> +{
> +       enum kvm_pgtable_prot prot;
> +       kvm_pte_t pte = *ptep;
> +
> +       /* If invalid, only allow to share pristine pages */
> +       if (!kvm_pte_valid(pte))
> +               return pte ? -EPERM : 0;
> +
> +       prot = kvm_pgtable_stage2_pte_prot(pte);
> +       if (!prot)
> +               return -EPERM;
> +
> +       /* Cannot share a page that is not owned */
> +       if (prot & KVM_PGTABLE_STATE_BORROWED)
> +               return -EPERM;
> +
> +       /* Cannot share a page with restricted access */
> +       if ((prot & KVM_PGTABLE_PROT_RWX) ^ KVM_PGTABLE_PROT_RWX)
nit: isn't this clearer as

if ((prot & KVM_PGTABLE_PROT_RWX) != KVM_PGTABLE_PROT_RWX)


> +               return -EPERM;
> +
> +       /* Allow double-sharing (requires cross-checking the hyp stage-1) */
> +       if (prot & KVM_PGTABLE_STATE_SHARED)
> +               return hyp_range_is_shared(addr, addr + 1);

Why addr+1, rather than end?

> +
> +       return 0;
> +}
> +
> +static int check_host_share_hyp(phys_addr_t start, phys_addr_t end)
> +{
> +       struct kvm_pgtable_walker walker = {
> +               .cb = check_host_share_hyp_walker,
> +               .flags = KVM_PGTABLE_WALK_LEAF,
> +       };
> +
> +       return kvm_pgtable_walk(&host_kvm.pgt, start, end - start, &walker);
> +}
> +
> +int __pkvm_host_share_hyp(phys_addr_t start, phys_addr_t end)
> +{
> +       enum kvm_pgtable_prot prot;
> +       int ret;
> +
> +       if (!range_is_memory(start, end))
> +               return -EINVAL;
> +
> +       hyp_spin_lock(&host_kvm.lock);
> +       hyp_spin_lock(&pkvm_pgd_lock);
> +
> +       ret = check_host_share_hyp(start, end);
> +       if (ret)
> +               goto unlock;
> +
> +       prot = KVM_PGTABLE_PROT_RWX | KVM_PGTABLE_STATE_SHARED;
> +       ret = host_stage2_idmap_locked(start, end, prot);

Just for me to understand this better. The id mapping here, which
wasn't taking place before this patch, is for tracking, right?

Thanks,
/fuad


> +       if (ret && ret != -EAGAIN)
> +               goto unlock;
> +
> +       prot = PAGE_HYP | KVM_PGTABLE_STATE_SHARED | KVM_PGTABLE_STATE_BORROWED;
> +       ret = pkvm_create_mappings_locked(__hyp_va(start), __hyp_va(end), prot);
> +       /* XXX - undo host stage-2 changes if ret != 0 */
> +
> +unlock:
> +       hyp_spin_unlock(&pkvm_pgd_lock);
> +       hyp_spin_unlock(&host_kvm.lock);
> +
> +       return ret;
> +}
> +
>  int __pkvm_mark_hyp(phys_addr_t start, phys_addr_t end)
>  {
>         int ret;
> diff --git a/arch/arm64/kvm/hyp/nvhe/mm.c b/arch/arm64/kvm/hyp/nvhe/mm.c
> index dde22e2a322a..95f6c34a38ec 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mm.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mm.c
> @@ -23,8 +23,8 @@ u64 __io_map_base;
>  struct memblock_region hyp_memory[HYP_MEMBLOCK_REGIONS];
>  unsigned int hyp_memblock_nr;
>
> -int __pkvm_create_mappings(unsigned long start, unsigned long size,
> -                         unsigned long phys, enum kvm_pgtable_prot prot)
> +static int __pkvm_create_mappings(unsigned long start, unsigned long size,
> +                                 unsigned long phys, enum kvm_pgtable_prot prot)
>  {
>         int err;
>
> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> index 0625bf2353c2..2158d1e00acd 100644
> --- a/arch/arm64/kvm/mmu.c
> +++ b/arch/arm64/kvm/mmu.c
> @@ -259,10 +259,8 @@ static int __create_hyp_mappings(unsigned long start, unsigned long size,
>  {
>         int err;
>
> -       if (!kvm_host_owns_hyp_mappings()) {
> -               return kvm_call_hyp_nvhe(__pkvm_create_mappings,
> -                                        start, size, phys, prot);
> -       }
> +       if (WARN_ON(!kvm_host_owns_hyp_mappings()))
> +               return -EINVAL;
>
>         mutex_lock(&kvm_hyp_pgd_mutex);
>         err = kvm_pgtable_hyp_map(hyp_pgtable, start, size, phys, prot);
> @@ -302,6 +300,14 @@ int create_hyp_mappings(void *from, void *to, enum kvm_pgtable_prot prot)
>         if (is_kernel_in_hyp_mode())
>                 return 0;
>
> +       if (!kvm_host_owns_hyp_mappings()) {
> +               if (WARN_ON(prot != PAGE_HYP))
> +                       return -EPERM;
> +               return kvm_call_hyp_nvhe(__pkvm_host_share_hyp,
> +                                        kvm_kaddr_to_phys(from),
> +                                        kvm_kaddr_to_phys(to));
> +       }
> +
>         start = start & PAGE_MASK;
>         end = PAGE_ALIGN(end);
>
> --
> 2.32.0.402.g57bb445576-goog
>

WARNING: multiple messages have this Message-ID (diff)
From: Fuad Tabba <tabba@google.com>
To: Quentin Perret <qperret@google.com>
Cc: kernel-team@android.com, qwandor@google.com, maz@kernel.org,
	linux-kernel@vger.kernel.org, catalin.marinas@arm.com,
	will@kernel.org, kvmarm@lists.cs.columbia.edu,
	linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH 13/14] KVM: arm64: Restrict hyp stage-1 manipulation in protected mode
Date: Wed, 21 Jul 2021 11:45:53 +0100	[thread overview]
Message-ID: <CA+EHjTzpoX+rLQHwUbR3BVY_XJEWERiG4AGk7SW6GDtDFC_cuQ@mail.gmail.com> (raw)
In-Reply-To: <20210719104735.3681732-14-qperret@google.com>

Hi Quentin,

On Mon, Jul 19, 2021 at 11:48 AM Quentin Perret <qperret@google.com> wrote:
>
> The host kernel is currently able to change EL2 stage-1 mappings without
> restrictions thanks to the __pkvm_create_mappings() hypercall. But in a
> world where the host is no longer part of the TCB, this clearly poses a
> problem.
>
> To fix this, introduce a new hypercall to allow the host to share a
> range of physical memory with the hypervisor, and remove the
> __pkvm_create_mappings() variant. The new hypercall implements
> ownership and permission checks before allowing the sharing operation,
> and it annotates the shared pages in the hypervisor stage-1 and host
> stage-2 page-tables.
>
> Signed-off-by: Quentin Perret <qperret@google.com>
> ---
>  arch/arm64/include/asm/kvm_asm.h              |   2 +-
>  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |   1 +
>  arch/arm64/kvm/hyp/include/nvhe/mm.h          |   2 -
>  arch/arm64/kvm/hyp/nvhe/hyp-main.c            |  12 +-
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 105 ++++++++++++++++++
>  arch/arm64/kvm/hyp/nvhe/mm.c                  |   4 +-
>  arch/arm64/kvm/mmu.c                          |  14 ++-
>  7 files changed, 124 insertions(+), 16 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> index 9f0bf2109be7..78db818ae2c9 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -59,7 +59,7 @@
>  #define __KVM_HOST_SMCCC_FUNC___vgic_v3_save_aprs              13
>  #define __KVM_HOST_SMCCC_FUNC___vgic_v3_restore_aprs           14
>  #define __KVM_HOST_SMCCC_FUNC___pkvm_init                      15
> -#define __KVM_HOST_SMCCC_FUNC___pkvm_create_mappings           16
> +#define __KVM_HOST_SMCCC_FUNC___pkvm_host_share_hyp            16
>  #define __KVM_HOST_SMCCC_FUNC___pkvm_create_private_mapping    17
>  #define __KVM_HOST_SMCCC_FUNC___pkvm_cpu_set_vector            18
>  #define __KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize             19
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> index b39047463075..f37e4d3b831b 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> @@ -22,6 +22,7 @@ extern struct host_kvm host_kvm;
>
>  int __pkvm_prot_finalize(void);
>  int __pkvm_mark_hyp(phys_addr_t start, phys_addr_t end);
> +int __pkvm_host_share_hyp(phys_addr_t start, phys_addr_t end);
>
>  int host_stage2_idmap_locked(u64 start, u64 end, enum kvm_pgtable_prot prot);
>  int kvm_host_prepare_stage2(void *pgt_pool_base);
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mm.h b/arch/arm64/kvm/hyp/include/nvhe/mm.h
> index c76d7136ed9b..c9a8f535212e 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mm.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mm.h
> @@ -24,8 +24,6 @@ int hyp_back_vmemmap(phys_addr_t phys, unsigned long size, phys_addr_t back);
>  int pkvm_cpu_set_vector(enum arm64_hyp_spectre_vector slot);
>  int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot);
>  int pkvm_create_mappings_locked(void *from, void *to, enum kvm_pgtable_prot prot);
> -int __pkvm_create_mappings(unsigned long start, unsigned long size,
> -                          unsigned long phys, enum kvm_pgtable_prot prot);
>  unsigned long __pkvm_create_private_mapping(phys_addr_t phys, size_t size,
>                                             enum kvm_pgtable_prot prot);
>
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index 1632f001f4ed..f05ecbd382d0 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -140,14 +140,12 @@ static void handle___pkvm_cpu_set_vector(struct kvm_cpu_context *host_ctxt)
>         cpu_reg(host_ctxt, 1) = pkvm_cpu_set_vector(slot);
>  }
>
> -static void handle___pkvm_create_mappings(struct kvm_cpu_context *host_ctxt)
> +static void handle___pkvm_host_share_hyp(struct kvm_cpu_context *host_ctxt)
>  {
> -       DECLARE_REG(unsigned long, start, host_ctxt, 1);
> -       DECLARE_REG(unsigned long, size, host_ctxt, 2);
> -       DECLARE_REG(unsigned long, phys, host_ctxt, 3);
> -       DECLARE_REG(enum kvm_pgtable_prot, prot, host_ctxt, 4);
> +       DECLARE_REG(phys_addr_t, start, host_ctxt, 1);
> +       DECLARE_REG(phys_addr_t, end, host_ctxt, 2);
>
> -       cpu_reg(host_ctxt, 1) = __pkvm_create_mappings(start, size, phys, prot);
> +       cpu_reg(host_ctxt, 1) = __pkvm_host_share_hyp(start, end);
>  }
>
>  static void handle___pkvm_create_private_mapping(struct kvm_cpu_context *host_ctxt)
> @@ -193,7 +191,7 @@ static const hcall_t host_hcall[] = {
>         HANDLE_FUNC(__vgic_v3_restore_aprs),
>         HANDLE_FUNC(__pkvm_init),
>         HANDLE_FUNC(__pkvm_cpu_set_vector),
> -       HANDLE_FUNC(__pkvm_create_mappings),
> +       HANDLE_FUNC(__pkvm_host_share_hyp),
>         HANDLE_FUNC(__pkvm_create_private_mapping),
>         HANDLE_FUNC(__pkvm_prot_finalize),
>         HANDLE_FUNC(__pkvm_mark_hyp),
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index 6f28edf58407..20b3cb3fdc67 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -262,6 +262,111 @@ static int host_stage2_idmap(u64 addr)
>         return ret;
>  }
>
> +static int hyp_range_is_shared_walker(u64 addr, u64 end, u32 level,
> +                                     kvm_pte_t *ptep,
> +                                     enum kvm_pgtable_walk_flags flag,
> +                                     void * const arg)
> +{
> +       enum kvm_pgtable_prot prot;
> +       kvm_pte_t pte = *ptep;
> +
> +       if (!kvm_pte_valid(pte))
> +               return -EPERM;
> +
> +       prot = kvm_pgtable_hyp_pte_prot(pte);
> +       if (!prot)
> +               return -EPERM;
nit: is this check necessary?

> +       /* Check that the page has been shared with the hypervisor before */
> +       if (prot != (PAGE_HYP | KVM_PGTABLE_STATE_SHARED | KVM_PGTABLE_STATE_BORROWED))
> +               return -EPERM;
> +
> +       return 0;
> +}
> +
> +static int hyp_range_is_shared(phys_addr_t start, phys_addr_t end)
> +{
> +       struct kvm_pgtable_walker walker = {
> +               .cb = hyp_range_is_shared_walker,
> +               .flags = KVM_PGTABLE_WALK_LEAF,
> +       };
> +
> +       return kvm_pgtable_walk(&pkvm_pgtable, (u64)__hyp_va(start),
> +                               end - start, &walker);
> +}
> +
> +static int check_host_share_hyp_walker(u64 addr, u64 end, u32 level,

nit: It seems the convention is usually addr,size or start,end. Here
you're using addr,end.

> +                                      kvm_pte_t *ptep,
> +                                      enum kvm_pgtable_walk_flags flag,
> +                                      void * const arg)
> +{
> +       enum kvm_pgtable_prot prot;
> +       kvm_pte_t pte = *ptep;
> +
> +       /* If invalid, only allow to share pristine pages */
> +       if (!kvm_pte_valid(pte))
> +               return pte ? -EPERM : 0;
> +
> +       prot = kvm_pgtable_stage2_pte_prot(pte);
> +       if (!prot)
> +               return -EPERM;
> +
> +       /* Cannot share a page that is not owned */
> +       if (prot & KVM_PGTABLE_STATE_BORROWED)
> +               return -EPERM;
> +
> +       /* Cannot share a page with restricted access */
> +       if ((prot & KVM_PGTABLE_PROT_RWX) ^ KVM_PGTABLE_PROT_RWX)
nit: isn't this clearer as

if ((prot & KVM_PGTABLE_PROT_RWX) != KVM_PGTABLE_PROT_RWX)


> +               return -EPERM;
> +
> +       /* Allow double-sharing (requires cross-checking the hyp stage-1) */
> +       if (prot & KVM_PGTABLE_STATE_SHARED)
> +               return hyp_range_is_shared(addr, addr + 1);

Why addr+1, rather than end?

> +
> +       return 0;
> +}
> +
> +static int check_host_share_hyp(phys_addr_t start, phys_addr_t end)
> +{
> +       struct kvm_pgtable_walker walker = {
> +               .cb = check_host_share_hyp_walker,
> +               .flags = KVM_PGTABLE_WALK_LEAF,
> +       };
> +
> +       return kvm_pgtable_walk(&host_kvm.pgt, start, end - start, &walker);
> +}
> +
> +int __pkvm_host_share_hyp(phys_addr_t start, phys_addr_t end)
> +{
> +       enum kvm_pgtable_prot prot;
> +       int ret;
> +
> +       if (!range_is_memory(start, end))
> +               return -EINVAL;
> +
> +       hyp_spin_lock(&host_kvm.lock);
> +       hyp_spin_lock(&pkvm_pgd_lock);
> +
> +       ret = check_host_share_hyp(start, end);
> +       if (ret)
> +               goto unlock;
> +
> +       prot = KVM_PGTABLE_PROT_RWX | KVM_PGTABLE_STATE_SHARED;
> +       ret = host_stage2_idmap_locked(start, end, prot);

Just for me to understand this better. The id mapping here, which
wasn't taking place before this patch, is for tracking, right?

Thanks,
/fuad


> +       if (ret && ret != -EAGAIN)
> +               goto unlock;
> +
> +       prot = PAGE_HYP | KVM_PGTABLE_STATE_SHARED | KVM_PGTABLE_STATE_BORROWED;
> +       ret = pkvm_create_mappings_locked(__hyp_va(start), __hyp_va(end), prot);
> +       /* XXX - undo host stage-2 changes if ret != 0 */
> +
> +unlock:
> +       hyp_spin_unlock(&pkvm_pgd_lock);
> +       hyp_spin_unlock(&host_kvm.lock);
> +
> +       return ret;
> +}
> +
>  int __pkvm_mark_hyp(phys_addr_t start, phys_addr_t end)
>  {
>         int ret;
> diff --git a/arch/arm64/kvm/hyp/nvhe/mm.c b/arch/arm64/kvm/hyp/nvhe/mm.c
> index dde22e2a322a..95f6c34a38ec 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mm.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mm.c
> @@ -23,8 +23,8 @@ u64 __io_map_base;
>  struct memblock_region hyp_memory[HYP_MEMBLOCK_REGIONS];
>  unsigned int hyp_memblock_nr;
>
> -int __pkvm_create_mappings(unsigned long start, unsigned long size,
> -                         unsigned long phys, enum kvm_pgtable_prot prot)
> +static int __pkvm_create_mappings(unsigned long start, unsigned long size,
> +                                 unsigned long phys, enum kvm_pgtable_prot prot)
>  {
>         int err;
>
> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> index 0625bf2353c2..2158d1e00acd 100644
> --- a/arch/arm64/kvm/mmu.c
> +++ b/arch/arm64/kvm/mmu.c
> @@ -259,10 +259,8 @@ static int __create_hyp_mappings(unsigned long start, unsigned long size,
>  {
>         int err;
>
> -       if (!kvm_host_owns_hyp_mappings()) {
> -               return kvm_call_hyp_nvhe(__pkvm_create_mappings,
> -                                        start, size, phys, prot);
> -       }
> +       if (WARN_ON(!kvm_host_owns_hyp_mappings()))
> +               return -EINVAL;
>
>         mutex_lock(&kvm_hyp_pgd_mutex);
>         err = kvm_pgtable_hyp_map(hyp_pgtable, start, size, phys, prot);
> @@ -302,6 +300,14 @@ int create_hyp_mappings(void *from, void *to, enum kvm_pgtable_prot prot)
>         if (is_kernel_in_hyp_mode())
>                 return 0;
>
> +       if (!kvm_host_owns_hyp_mappings()) {
> +               if (WARN_ON(prot != PAGE_HYP))
> +                       return -EPERM;
> +               return kvm_call_hyp_nvhe(__pkvm_host_share_hyp,
> +                                        kvm_kaddr_to_phys(from),
> +                                        kvm_kaddr_to_phys(to));
> +       }
> +
>         start = start & PAGE_MASK;
>         end = PAGE_ALIGN(end);
>
> --
> 2.32.0.402.g57bb445576-goog
>
_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

WARNING: multiple messages have this Message-ID (diff)
From: Fuad Tabba <tabba@google.com>
To: Quentin Perret <qperret@google.com>
Cc: maz@kernel.org, james.morse@arm.com, alexandru.elisei@arm.com,
	 suzuki.poulose@arm.com, catalin.marinas@arm.com,
	will@kernel.org,  linux-arm-kernel@lists.infradead.org,
	kvmarm@lists.cs.columbia.edu,  linux-kernel@vger.kernel.org,
	ardb@kernel.org, qwandor@google.com,  dbrazdil@google.com,
	kernel-team@android.com
Subject: Re: [PATCH 13/14] KVM: arm64: Restrict hyp stage-1 manipulation in protected mode
Date: Wed, 21 Jul 2021 11:45:53 +0100	[thread overview]
Message-ID: <CA+EHjTzpoX+rLQHwUbR3BVY_XJEWERiG4AGk7SW6GDtDFC_cuQ@mail.gmail.com> (raw)
In-Reply-To: <20210719104735.3681732-14-qperret@google.com>

Hi Quentin,

On Mon, Jul 19, 2021 at 11:48 AM Quentin Perret <qperret@google.com> wrote:
>
> The host kernel is currently able to change EL2 stage-1 mappings without
> restrictions thanks to the __pkvm_create_mappings() hypercall. But in a
> world where the host is no longer part of the TCB, this clearly poses a
> problem.
>
> To fix this, introduce a new hypercall to allow the host to share a
> range of physical memory with the hypervisor, and remove the
> __pkvm_create_mappings() variant. The new hypercall implements
> ownership and permission checks before allowing the sharing operation,
> and it annotates the shared pages in the hypervisor stage-1 and host
> stage-2 page-tables.
>
> Signed-off-by: Quentin Perret <qperret@google.com>
> ---
>  arch/arm64/include/asm/kvm_asm.h              |   2 +-
>  arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |   1 +
>  arch/arm64/kvm/hyp/include/nvhe/mm.h          |   2 -
>  arch/arm64/kvm/hyp/nvhe/hyp-main.c            |  12 +-
>  arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 105 ++++++++++++++++++
>  arch/arm64/kvm/hyp/nvhe/mm.c                  |   4 +-
>  arch/arm64/kvm/mmu.c                          |  14 ++-
>  7 files changed, 124 insertions(+), 16 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
> index 9f0bf2109be7..78db818ae2c9 100644
> --- a/arch/arm64/include/asm/kvm_asm.h
> +++ b/arch/arm64/include/asm/kvm_asm.h
> @@ -59,7 +59,7 @@
>  #define __KVM_HOST_SMCCC_FUNC___vgic_v3_save_aprs              13
>  #define __KVM_HOST_SMCCC_FUNC___vgic_v3_restore_aprs           14
>  #define __KVM_HOST_SMCCC_FUNC___pkvm_init                      15
> -#define __KVM_HOST_SMCCC_FUNC___pkvm_create_mappings           16
> +#define __KVM_HOST_SMCCC_FUNC___pkvm_host_share_hyp            16
>  #define __KVM_HOST_SMCCC_FUNC___pkvm_create_private_mapping    17
>  #define __KVM_HOST_SMCCC_FUNC___pkvm_cpu_set_vector            18
>  #define __KVM_HOST_SMCCC_FUNC___pkvm_prot_finalize             19
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> index b39047463075..f37e4d3b831b 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h
> @@ -22,6 +22,7 @@ extern struct host_kvm host_kvm;
>
>  int __pkvm_prot_finalize(void);
>  int __pkvm_mark_hyp(phys_addr_t start, phys_addr_t end);
> +int __pkvm_host_share_hyp(phys_addr_t start, phys_addr_t end);
>
>  int host_stage2_idmap_locked(u64 start, u64 end, enum kvm_pgtable_prot prot);
>  int kvm_host_prepare_stage2(void *pgt_pool_base);
> diff --git a/arch/arm64/kvm/hyp/include/nvhe/mm.h b/arch/arm64/kvm/hyp/include/nvhe/mm.h
> index c76d7136ed9b..c9a8f535212e 100644
> --- a/arch/arm64/kvm/hyp/include/nvhe/mm.h
> +++ b/arch/arm64/kvm/hyp/include/nvhe/mm.h
> @@ -24,8 +24,6 @@ int hyp_back_vmemmap(phys_addr_t phys, unsigned long size, phys_addr_t back);
>  int pkvm_cpu_set_vector(enum arm64_hyp_spectre_vector slot);
>  int pkvm_create_mappings(void *from, void *to, enum kvm_pgtable_prot prot);
>  int pkvm_create_mappings_locked(void *from, void *to, enum kvm_pgtable_prot prot);
> -int __pkvm_create_mappings(unsigned long start, unsigned long size,
> -                          unsigned long phys, enum kvm_pgtable_prot prot);
>  unsigned long __pkvm_create_private_mapping(phys_addr_t phys, size_t size,
>                                             enum kvm_pgtable_prot prot);
>
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index 1632f001f4ed..f05ecbd382d0 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -140,14 +140,12 @@ static void handle___pkvm_cpu_set_vector(struct kvm_cpu_context *host_ctxt)
>         cpu_reg(host_ctxt, 1) = pkvm_cpu_set_vector(slot);
>  }
>
> -static void handle___pkvm_create_mappings(struct kvm_cpu_context *host_ctxt)
> +static void handle___pkvm_host_share_hyp(struct kvm_cpu_context *host_ctxt)
>  {
> -       DECLARE_REG(unsigned long, start, host_ctxt, 1);
> -       DECLARE_REG(unsigned long, size, host_ctxt, 2);
> -       DECLARE_REG(unsigned long, phys, host_ctxt, 3);
> -       DECLARE_REG(enum kvm_pgtable_prot, prot, host_ctxt, 4);
> +       DECLARE_REG(phys_addr_t, start, host_ctxt, 1);
> +       DECLARE_REG(phys_addr_t, end, host_ctxt, 2);
>
> -       cpu_reg(host_ctxt, 1) = __pkvm_create_mappings(start, size, phys, prot);
> +       cpu_reg(host_ctxt, 1) = __pkvm_host_share_hyp(start, end);
>  }
>
>  static void handle___pkvm_create_private_mapping(struct kvm_cpu_context *host_ctxt)
> @@ -193,7 +191,7 @@ static const hcall_t host_hcall[] = {
>         HANDLE_FUNC(__vgic_v3_restore_aprs),
>         HANDLE_FUNC(__pkvm_init),
>         HANDLE_FUNC(__pkvm_cpu_set_vector),
> -       HANDLE_FUNC(__pkvm_create_mappings),
> +       HANDLE_FUNC(__pkvm_host_share_hyp),
>         HANDLE_FUNC(__pkvm_create_private_mapping),
>         HANDLE_FUNC(__pkvm_prot_finalize),
>         HANDLE_FUNC(__pkvm_mark_hyp),
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index 6f28edf58407..20b3cb3fdc67 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -262,6 +262,111 @@ static int host_stage2_idmap(u64 addr)
>         return ret;
>  }
>
> +static int hyp_range_is_shared_walker(u64 addr, u64 end, u32 level,
> +                                     kvm_pte_t *ptep,
> +                                     enum kvm_pgtable_walk_flags flag,
> +                                     void * const arg)
> +{
> +       enum kvm_pgtable_prot prot;
> +       kvm_pte_t pte = *ptep;
> +
> +       if (!kvm_pte_valid(pte))
> +               return -EPERM;
> +
> +       prot = kvm_pgtable_hyp_pte_prot(pte);
> +       if (!prot)
> +               return -EPERM;
nit: is this check necessary?

> +       /* Check that the page has been shared with the hypervisor before */
> +       if (prot != (PAGE_HYP | KVM_PGTABLE_STATE_SHARED | KVM_PGTABLE_STATE_BORROWED))
> +               return -EPERM;
> +
> +       return 0;
> +}
> +
> +static int hyp_range_is_shared(phys_addr_t start, phys_addr_t end)
> +{
> +       struct kvm_pgtable_walker walker = {
> +               .cb = hyp_range_is_shared_walker,
> +               .flags = KVM_PGTABLE_WALK_LEAF,
> +       };
> +
> +       return kvm_pgtable_walk(&pkvm_pgtable, (u64)__hyp_va(start),
> +                               end - start, &walker);
> +}
> +
> +static int check_host_share_hyp_walker(u64 addr, u64 end, u32 level,

nit: It seems the convention is usually addr,size or start,end. Here
you're using addr,end.

> +                                      kvm_pte_t *ptep,
> +                                      enum kvm_pgtable_walk_flags flag,
> +                                      void * const arg)
> +{
> +       enum kvm_pgtable_prot prot;
> +       kvm_pte_t pte = *ptep;
> +
> +       /* If invalid, only allow to share pristine pages */
> +       if (!kvm_pte_valid(pte))
> +               return pte ? -EPERM : 0;
> +
> +       prot = kvm_pgtable_stage2_pte_prot(pte);
> +       if (!prot)
> +               return -EPERM;
> +
> +       /* Cannot share a page that is not owned */
> +       if (prot & KVM_PGTABLE_STATE_BORROWED)
> +               return -EPERM;
> +
> +       /* Cannot share a page with restricted access */
> +       if ((prot & KVM_PGTABLE_PROT_RWX) ^ KVM_PGTABLE_PROT_RWX)
nit: isn't this clearer as

if ((prot & KVM_PGTABLE_PROT_RWX) != KVM_PGTABLE_PROT_RWX)


> +               return -EPERM;
> +
> +       /* Allow double-sharing (requires cross-checking the hyp stage-1) */
> +       if (prot & KVM_PGTABLE_STATE_SHARED)
> +               return hyp_range_is_shared(addr, addr + 1);

Why addr+1, rather than end?

> +
> +       return 0;
> +}
> +
> +static int check_host_share_hyp(phys_addr_t start, phys_addr_t end)
> +{
> +       struct kvm_pgtable_walker walker = {
> +               .cb = check_host_share_hyp_walker,
> +               .flags = KVM_PGTABLE_WALK_LEAF,
> +       };
> +
> +       return kvm_pgtable_walk(&host_kvm.pgt, start, end - start, &walker);
> +}
> +
> +int __pkvm_host_share_hyp(phys_addr_t start, phys_addr_t end)
> +{
> +       enum kvm_pgtable_prot prot;
> +       int ret;
> +
> +       if (!range_is_memory(start, end))
> +               return -EINVAL;
> +
> +       hyp_spin_lock(&host_kvm.lock);
> +       hyp_spin_lock(&pkvm_pgd_lock);
> +
> +       ret = check_host_share_hyp(start, end);
> +       if (ret)
> +               goto unlock;
> +
> +       prot = KVM_PGTABLE_PROT_RWX | KVM_PGTABLE_STATE_SHARED;
> +       ret = host_stage2_idmap_locked(start, end, prot);

Just for me to understand this better. The id mapping here, which
wasn't taking place before this patch, is for tracking, right?

Thanks,
/fuad


> +       if (ret && ret != -EAGAIN)
> +               goto unlock;
> +
> +       prot = PAGE_HYP | KVM_PGTABLE_STATE_SHARED | KVM_PGTABLE_STATE_BORROWED;
> +       ret = pkvm_create_mappings_locked(__hyp_va(start), __hyp_va(end), prot);
> +       /* XXX - undo host stage-2 changes if ret != 0 */
> +
> +unlock:
> +       hyp_spin_unlock(&pkvm_pgd_lock);
> +       hyp_spin_unlock(&host_kvm.lock);
> +
> +       return ret;
> +}
> +
>  int __pkvm_mark_hyp(phys_addr_t start, phys_addr_t end)
>  {
>         int ret;
> diff --git a/arch/arm64/kvm/hyp/nvhe/mm.c b/arch/arm64/kvm/hyp/nvhe/mm.c
> index dde22e2a322a..95f6c34a38ec 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mm.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mm.c
> @@ -23,8 +23,8 @@ u64 __io_map_base;
>  struct memblock_region hyp_memory[HYP_MEMBLOCK_REGIONS];
>  unsigned int hyp_memblock_nr;
>
> -int __pkvm_create_mappings(unsigned long start, unsigned long size,
> -                         unsigned long phys, enum kvm_pgtable_prot prot)
> +static int __pkvm_create_mappings(unsigned long start, unsigned long size,
> +                                 unsigned long phys, enum kvm_pgtable_prot prot)
>  {
>         int err;
>
> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> index 0625bf2353c2..2158d1e00acd 100644
> --- a/arch/arm64/kvm/mmu.c
> +++ b/arch/arm64/kvm/mmu.c
> @@ -259,10 +259,8 @@ static int __create_hyp_mappings(unsigned long start, unsigned long size,
>  {
>         int err;
>
> -       if (!kvm_host_owns_hyp_mappings()) {
> -               return kvm_call_hyp_nvhe(__pkvm_create_mappings,
> -                                        start, size, phys, prot);
> -       }
> +       if (WARN_ON(!kvm_host_owns_hyp_mappings()))
> +               return -EINVAL;
>
>         mutex_lock(&kvm_hyp_pgd_mutex);
>         err = kvm_pgtable_hyp_map(hyp_pgtable, start, size, phys, prot);
> @@ -302,6 +300,14 @@ int create_hyp_mappings(void *from, void *to, enum kvm_pgtable_prot prot)
>         if (is_kernel_in_hyp_mode())
>                 return 0;
>
> +       if (!kvm_host_owns_hyp_mappings()) {
> +               if (WARN_ON(prot != PAGE_HYP))
> +                       return -EPERM;
> +               return kvm_call_hyp_nvhe(__pkvm_host_share_hyp,
> +                                        kvm_kaddr_to_phys(from),
> +                                        kvm_kaddr_to_phys(to));
> +       }
> +
>         start = start & PAGE_MASK;
>         end = PAGE_ALIGN(end);
>
> --
> 2.32.0.402.g57bb445576-goog
>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2021-07-21 10:54 UTC|newest]

Thread overview: 126+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-19 10:47 [PATCH 00/14] Track shared pages at EL2 in protected mode Quentin Perret
2021-07-19 10:47 ` Quentin Perret
2021-07-19 10:47 ` Quentin Perret
2021-07-19 10:47 ` [PATCH 01/14] KVM: arm64: Provide the host_stage2_try() helper macro Quentin Perret
2021-07-19 10:47   ` Quentin Perret
2021-07-19 10:47   ` Quentin Perret
2021-07-20 13:57   ` Fuad Tabba
2021-07-20 13:57     ` Fuad Tabba
2021-07-20 13:57     ` Fuad Tabba
2021-07-19 10:47 ` [PATCH 02/14] KVM: arm64: Optimize kvm_pgtable_stage2_find_range() Quentin Perret
2021-07-19 10:47   ` Quentin Perret
2021-07-19 10:47   ` Quentin Perret
2021-07-19 10:47 ` [PATCH 03/14] KVM: arm64: Continue stage-2 map when re-creating mappings Quentin Perret
2021-07-19 10:47   ` Quentin Perret
2021-07-19 10:47   ` Quentin Perret
2021-07-19 12:14   ` Marc Zyngier
2021-07-19 12:14     ` Marc Zyngier
2021-07-19 12:14     ` Marc Zyngier
2021-07-19 13:32     ` Quentin Perret
2021-07-19 13:32       ` Quentin Perret
2021-07-19 13:32       ` Quentin Perret
2021-07-20  8:26       ` Marc Zyngier
2021-07-20  8:26         ` Marc Zyngier
2021-07-20  8:26         ` Marc Zyngier
2021-07-20 11:56         ` Quentin Perret
2021-07-20 11:56           ` Quentin Perret
2021-07-20 11:56           ` Quentin Perret
2021-07-19 10:47 ` [PATCH 04/14] KVM: arm64: Rename KVM_PTE_LEAF_ATTR_S2_IGNORED Quentin Perret
2021-07-19 10:47   ` Quentin Perret
2021-07-19 10:47   ` Quentin Perret
2021-07-19 10:47 ` [PATCH 05/14] KVM: arm64: Don't overwrite ignored bits with owner id Quentin Perret
2021-07-19 10:47   ` Quentin Perret
2021-07-19 10:47   ` Quentin Perret
2021-07-19 12:55   ` Marc Zyngier
2021-07-19 12:55     ` Marc Zyngier
2021-07-19 12:55     ` Marc Zyngier
2021-07-19 13:39     ` Quentin Perret
2021-07-19 13:39       ` Quentin Perret
2021-07-19 13:39       ` Quentin Perret
2021-07-20  8:46       ` Marc Zyngier
2021-07-20  8:46         ` Marc Zyngier
2021-07-20  8:46         ` Marc Zyngier
2021-07-19 10:47 ` [PATCH 06/14] KVM: arm64: Tolerate re-creating hyp mappings to set ignored bits Quentin Perret
2021-07-19 10:47   ` Quentin Perret
2021-07-19 10:47   ` Quentin Perret
2021-07-20 10:17   ` Fuad Tabba
2021-07-20 10:17     ` Fuad Tabba
2021-07-20 10:17     ` Fuad Tabba
2021-07-20 10:30     ` Quentin Perret
2021-07-20 10:30       ` Quentin Perret
2021-07-20 10:30       ` Quentin Perret
2021-07-20 10:59       ` Fuad Tabba
2021-07-20 10:59         ` Fuad Tabba
2021-07-20 10:59         ` Fuad Tabba
2021-07-20 11:14         ` Quentin Perret
2021-07-20 11:14           ` Quentin Perret
2021-07-20 11:14           ` Quentin Perret
2021-07-19 10:47 ` [PATCH 07/14] KVM: arm64: Enable forcing page-level stage-2 mappings Quentin Perret
2021-07-19 10:47   ` Quentin Perret
2021-07-19 10:47   ` Quentin Perret
2021-07-19 14:24   ` Marc Zyngier
2021-07-19 14:24     ` Marc Zyngier
2021-07-19 14:24     ` Marc Zyngier
2021-07-19 15:36     ` Quentin Perret
2021-07-19 15:36       ` Quentin Perret
2021-07-19 15:36       ` Quentin Perret
2021-07-19 10:47 ` [PATCH 08/14] KVM: arm64: Add support for tagging shared pages in page-table Quentin Perret
2021-07-19 10:47   ` Quentin Perret
2021-07-19 10:47   ` Quentin Perret
2021-07-19 14:43   ` Marc Zyngier
2021-07-19 14:43     ` Marc Zyngier
2021-07-19 14:43     ` Marc Zyngier
2021-07-19 15:49     ` Quentin Perret
2021-07-19 15:49       ` Quentin Perret
2021-07-19 15:49       ` Quentin Perret
2021-07-20 10:13       ` Marc Zyngier
2021-07-20 10:13         ` Marc Zyngier
2021-07-20 10:13         ` Marc Zyngier
2021-07-20 11:48         ` Quentin Perret
2021-07-20 11:48           ` Quentin Perret
2021-07-20 11:48           ` Quentin Perret
2021-07-20 13:48   ` Fuad Tabba
2021-07-20 13:48     ` Fuad Tabba
2021-07-20 13:48     ` Fuad Tabba
2021-07-20 14:06     ` Quentin Perret
2021-07-20 14:06       ` Quentin Perret
2021-07-20 14:06       ` Quentin Perret
2021-07-21  7:34       ` Fuad Tabba
2021-07-21  7:34         ` Fuad Tabba
2021-07-21  7:34         ` Fuad Tabba
2021-07-19 10:47 ` [PATCH 09/14] KVM: arm64: Mark host bss and rodata section as shared Quentin Perret
2021-07-19 10:47   ` Quentin Perret
2021-07-19 10:47   ` Quentin Perret
2021-07-19 15:01   ` Marc Zyngier
2021-07-19 15:01     ` Marc Zyngier
2021-07-19 15:01     ` Marc Zyngier
2021-07-19 15:56     ` Quentin Perret
2021-07-19 15:56       ` Quentin Perret
2021-07-19 15:56       ` Quentin Perret
2021-07-19 10:47 ` [PATCH 10/14] KVM: arm64: Enable retrieving protections attributes of PTEs Quentin Perret
2021-07-19 10:47   ` Quentin Perret
2021-07-19 10:47   ` Quentin Perret
2021-07-19 10:47 ` [PATCH 11/14] KVM: arm64: Expose kvm_pte_valid() helper Quentin Perret
2021-07-19 10:47   ` Quentin Perret
2021-07-19 10:47   ` Quentin Perret
2021-07-21  8:20   ` Fuad Tabba
2021-07-21  8:20     ` Fuad Tabba
2021-07-21  8:20     ` Fuad Tabba
2021-07-19 10:47 ` [PATCH 12/14] KVM: arm64: Refactor pkvm_pgtable locking Quentin Perret
2021-07-19 10:47   ` Quentin Perret
2021-07-19 10:47   ` Quentin Perret
2021-07-21  8:37   ` Fuad Tabba
2021-07-21  8:37     ` Fuad Tabba
2021-07-21  8:37     ` Fuad Tabba
2021-07-19 10:47 ` [PATCH 13/14] KVM: arm64: Restrict hyp stage-1 manipulation in protected mode Quentin Perret
2021-07-19 10:47   ` Quentin Perret
2021-07-19 10:47   ` Quentin Perret
2021-07-21 10:45   ` Fuad Tabba [this message]
2021-07-21 10:45     ` Fuad Tabba
2021-07-21 10:45     ` Fuad Tabba
2021-07-21 13:35     ` Quentin Perret
2021-07-21 13:35       ` Quentin Perret
2021-07-21 13:35       ` Quentin Perret
2021-07-19 10:47 ` [PATCH 14/14] KVM: arm64: Prevent late calls to __pkvm_create_private_mapping() Quentin Perret
2021-07-19 10:47   ` Quentin Perret
2021-07-19 10:47   ` Quentin Perret

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CA+EHjTzpoX+rLQHwUbR3BVY_XJEWERiG4AGk7SW6GDtDFC_cuQ@mail.gmail.com \
    --to=tabba@google.com \
    --cc=alexandru.elisei@arm.com \
    --cc=ardb@kernel.org \
    --cc=catalin.marinas@arm.com \
    --cc=dbrazdil@google.com \
    --cc=james.morse@arm.com \
    --cc=kernel-team@android.com \
    --cc=kvmarm@lists.cs.columbia.edu \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=maz@kernel.org \
    --cc=qperret@google.com \
    --cc=qwandor@google.com \
    --cc=suzuki.poulose@arm.com \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.