Re: [PATCH v3 32/32] KVM: arm64: Protect the .hyp sections from the host

From: Will Deacon
Date: Fri Mar 05 2021 - 14:14:31 EST


On Tue, Mar 02, 2021 at 03:00:02PM +0000, Quentin Perret wrote:
> When KVM runs in nVHE protected mode, use the host stage 2 to unmap the
> hypervisor sections. 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.
>
> Signed-off-by: Quentin Perret <qperret@xxxxxxxxxx>
> ---
> arch/arm64/include/asm/kvm_asm.h | 1 +
> arch/arm64/kvm/arm.c | 46 +++++++++++++++++++
> arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 2 +
> arch/arm64/kvm/hyp/nvhe/hyp-main.c | 9 ++++
> arch/arm64/kvm/hyp/nvhe/mem_protect.c | 22 +++++++++
> 5 files changed, 80 insertions(+)

[...]

> static void handle_host_hcall(struct kvm_cpu_context *host_ctxt)
> diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> index 2252ad1a8945..ed480facdc88 100644
> --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
> @@ -196,6 +196,28 @@ static int host_stage2_idmap(u64 addr)
> return ret;
> }
>
> +int __pkvm_host_unmap(phys_addr_t start, phys_addr_t end)
> +{
> + struct kvm_mem_range r1, r2;
> + int ret;
> +
> + /*
> + * host_stage2_unmap_dev_all() currently relies on MMIO mappings being
> + * non-persistent, so don't allow PROT_NONE in MMIO range.
> + */
> + if (!find_mem_range(start, &r1) || !find_mem_range(end, &r2))
> + return -EINVAL;
> + if (r1.start != r2.start)
> + return -EINVAL;


Feels like this should be in a helper to determine whether or not a range is
solely covered by memory.

Either way:

Acked-by: Will Deacon <will@xxxxxxxxxx>

Will