All of lore.kernel.org
 help / color / mirror / Atom feed
From: Quentin Perret <qperret@google.com>
To: Will Deacon <will@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>,
	Marc Zyngier <maz@kernel.org>, James Morse <james.morse@arm.com>,
	Julien Thierry <julien.thierry.kdev@gmail.com>,
	Suzuki K Poulose <suzuki.poulose@arm.com>,
	Rob Herring <robh+dt@kernel.org>,
	Frank Rowand <frowand.list@gmail.com>,
	devicetree@vger.kernel.org, android-kvm@google.com,
	linux-kernel@vger.kernel.org, kernel-team@android.com,
	kvmarm@lists.cs.columbia.edu,
	linux-arm-kernel@lists.infradead.org,
	Fuad Tabba <tabba@google.com>,
	Mark Rutland <mark.rutland@arm.com>,
	David Brazdil <dbrazdil@google.com>
Subject: Re: [RFC PATCH v2 17/26] KVM: arm64: Elevate Hyp mappings creation at EL2
Date: Thu, 4 Feb 2021 11:08:33 +0000	[thread overview]
Message-ID: <YBvVseNd/r8q5He1@google.com> (raw)
In-Reply-To: <20210203153138.GB18974@willie-the-truck>

On Wednesday 03 Feb 2021 at 15:31:39 (+0000), Will Deacon wrote:
> On Fri, Jan 08, 2021 at 12:15:15PM +0000, Quentin Perret wrote:
> > Previous commits have introduced infrastructure at EL2 to enable the Hyp
> > code to manage its own memory, and more specifically its stage 1 page
> > tables. However, this was preliminary work, and none of it is currently
> > in use.
> > 
> > Put all of this together by elevating the hyp mappings creation at EL2
> > when memory protection is enabled. In this case, the host kernel running
> > at EL1 still creates _temporary_ Hyp 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.
> > 
> > Signed-off-by: Quentin Perret <qperret@google.com>
> > ---
> >  arch/arm64/include/asm/kvm_mmu.h |  1 -
> >  arch/arm64/kvm/arm.c             | 62 +++++++++++++++++++++++++++++---
> >  arch/arm64/kvm/mmu.c             | 34 ++++++++++++++++++
> >  3 files changed, 92 insertions(+), 5 deletions(-)
> > 
> > diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
> > index d7ebd73ec86f..6c8466a042a9 100644
> > --- a/arch/arm64/include/asm/kvm_mmu.h
> > +++ b/arch/arm64/include/asm/kvm_mmu.h
> > @@ -309,6 +309,5 @@ static __always_inline void __load_guest_stage2(struct kvm_s2_mmu *mmu)
> >  	 */
> >  	asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_SPECULATIVE_AT));
> >  }
> > -
> >  #endif /* __ASSEMBLY__ */
> >  #endif /* __ARM64_KVM_MMU_H__ */
> > diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> > index 6af9204bcd5b..e524682c2ccf 100644
> > --- a/arch/arm64/kvm/arm.c
> > +++ b/arch/arm64/kvm/arm.c
> > @@ -1421,7 +1421,7 @@ static void cpu_prepare_hyp_mode(int cpu)
> >  	kvm_flush_dcache_to_poc(params, sizeof(*params));
> >  }
> >  
> > -static void cpu_init_hyp_mode(void)
> > +static void kvm_set_hyp_vector(void)
> 
> Please do something about the naming: now we have both cpu_set_hyp_vector()
> and kvm_set_hyp_vector()!

I'll try to find something different, but no guarantees it'll be much
better :) Suggestions welcome.

> >  {
> >  	struct kvm_nvhe_init_params *params;
> >  	struct arm_smccc_res res;
> > @@ -1439,6 +1439,11 @@ static void cpu_init_hyp_mode(void)
> >  	params = this_cpu_ptr_nvhe_sym(kvm_init_params);
> >  	arm_smccc_1_1_hvc(KVM_HOST_SMCCC_FUNC(__kvm_hyp_init), virt_to_phys(params), &res);
> >  	WARN_ON(res.a0 != SMCCC_RET_SUCCESS);
> > +}
> > +
> > +static void cpu_init_hyp_mode(void)
> > +{
> > +	kvm_set_hyp_vector();
> >  
> >  	/*
> >  	 * Disabling SSBD on a non-VHE system requires us to enable SSBS
> > @@ -1481,7 +1486,10 @@ static void cpu_set_hyp_vector(void)
> >  	struct bp_hardening_data *data = this_cpu_ptr(&bp_hardening_data);
> >  	void *vector = hyp_spectre_vector_selector[data->slot];
> >  
> > -	*this_cpu_ptr_hyp_sym(kvm_hyp_vector) = (unsigned long)vector;
> > +	if (!is_protected_kvm_enabled())
> > +		*this_cpu_ptr_hyp_sym(kvm_hyp_vector) = (unsigned long)vector;
> > +	else
> > +		kvm_call_hyp_nvhe(__pkvm_cpu_set_vector, data->slot);
> 
> *Very* minor nit, but it might be cleaner to have static inline functions
> with the same prototypes as the hypercalls, just to make the code even
> easier to read. e.g
> 
> 	if (!is_protected_kvm_enabled())
> 		_cpu_set_vector(data->slot);
> 	else
> 		kvm_call_hyp_nvhe(__pkvm_cpu_set_vector, data->slot);
> 
> you could then conceivably wrap that in a macro and avoid having the
> "is_protected_kvm_enabled()" checks explicit every time.

Happy to do this here, but are you suggesting to generalize this pattern
to other places as well?

> >  }
> >  
> >  static void cpu_hyp_reinit(void)
> > @@ -1489,13 +1497,14 @@ static void cpu_hyp_reinit(void)
> >  	kvm_init_host_cpu_context(&this_cpu_ptr_hyp_sym(kvm_host_data)->host_ctxt);
> >  
> >  	cpu_hyp_reset();
> > -	cpu_set_hyp_vector();
> >  
> >  	if (is_kernel_in_hyp_mode())
> >  		kvm_timer_init_vhe();
> >  	else
> >  		cpu_init_hyp_mode();
> >  
> > +	cpu_set_hyp_vector();
> > +
> >  	kvm_arm_init_debug();
> >  
> >  	if (vgic_present)
> > @@ -1714,13 +1723,52 @@ static int copy_cpu_ftr_regs(void)
> >  	return 0;
> >  }
> >  
> > +static int kvm_hyp_enable_protection(void)
> > +{
> > +	void *per_cpu_base = kvm_ksym_ref(kvm_arm_hyp_percpu_base);
> > +	int ret, cpu;
> > +	void *addr;
> > +
> > +	if (!is_protected_kvm_enabled())
> > +		return 0;
> 
> Maybe I'm hung up on my previous suggestion, but I feel like we shouldn't
> get here if protected kvm isn't enabled.

The alternative is to move this check next to the call site, but it
won't help much IMO.

> 
> > +	if (!hyp_mem_base)
> > +		return -ENOMEM;
> > +
> > +	addr = phys_to_virt(hyp_mem_base);
> > +	ret = create_hyp_mappings(addr, addr + hyp_mem_size - 1, PAGE_HYP);
> > +	if (ret)
> > +		return ret;
> > +
> > +	preempt_disable();
> > +	kvm_set_hyp_vector();
> > +	ret = kvm_call_hyp_nvhe(__pkvm_init, hyp_mem_base, hyp_mem_size,
> > +				num_possible_cpus(), kern_hyp_va(per_cpu_base));
> 
> Would it make sense for the __pkvm_init() hypercall to set the vector as
> well, so that we wouldn't need to disable preemption over two hypercalls?

Not sure, kvm_set_hyp_vector() itself already does multiple hypercalls,
and I need it separate from __pkvm_init for secondary CPUs.

> Failing that, maybe move the whole preempt_disable/enable sequence into
> another function.

But that I can do.

> > +	preempt_enable();
> > +	if (ret)
> > +		return ret;
> > +
> > +	free_hyp_pgds();
> > +	for_each_possible_cpu(cpu)
> > +		free_page(per_cpu(kvm_arm_hyp_stack_page, cpu));
> > +
> > +	return 0;
> > +}
> > +
> >  /**
> >   * Inits Hyp-mode on all online CPUs
> >   */
> >  static int init_hyp_mode(void)
> >  {
> >  	int cpu;
> > -	int err = 0;
> > +	int err = -ENOMEM;
> > +
> > +	/*
> > +	 * The protected Hyp-mode cannot be initialized if the memory pool
> > +	 * allocation has failed.
> > +	 */
> > +	if (is_protected_kvm_enabled() && !hyp_mem_base)
> > +		return err;
> >  
> >  	/*
> >  	 * Copy the required CPU feature register in their EL2 counterpart
> > @@ -1854,6 +1902,12 @@ static int init_hyp_mode(void)
> >  	for_each_possible_cpu(cpu)
> >  		cpu_prepare_hyp_mode(cpu);
> >  
> > +	err = kvm_hyp_enable_protection();
> > +	if (err) {
> > +		kvm_err("Failed to enable hyp memory protection: %d\n", err);
> > +		goto out_err;
> > +	}
> > +
> >  	return 0;
> >  
> >  out_err:
> > diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> > index 3cf9397dabdb..9d4c9251208e 100644
> > --- a/arch/arm64/kvm/mmu.c
> > +++ b/arch/arm64/kvm/mmu.c
> > @@ -225,15 +225,39 @@ void free_hyp_pgds(void)
> >  	if (hyp_pgtable) {
> >  		kvm_pgtable_hyp_destroy(hyp_pgtable);
> >  		kfree(hyp_pgtable);
> > +		hyp_pgtable = NULL;
> >  	}
> >  	mutex_unlock(&kvm_hyp_pgd_mutex);
> >  }
> >  
> > +static bool kvm_host_owns_hyp_mappings(void)
> > +{
> > +	if (static_branch_likely(&kvm_protected_mode_initialized))
> > +		return false;
> > +
> > +	/*
> > +	 * This can happen at boot time when __create_hyp_mappings() is called
> > +	 * after the hyp protection has been enabled, but the static key has
> > +	 * not been flipped yet.
> > +	 */
> > +	if (!hyp_pgtable && is_protected_kvm_enabled())
> > +		return false;
> > +
> > +	BUG_ON(!hyp_pgtable);
> 
> Can we fail more gracefully, e.g. by continuing without KVM?

Got any suggestion as to how that can be done? We could also just remove
that line -- that really should not happen.

Thanks!
Quentin

WARNING: multiple messages have this Message-ID (diff)
From: Quentin Perret <qperret@google.com>
To: Will Deacon <will@kernel.org>
Cc: devicetree@vger.kernel.org, kernel-team@android.com,
	android-kvm@google.com, Catalin Marinas <catalin.marinas@arm.com>,
	Fuad Tabba <tabba@google.com>,
	linux-kernel@vger.kernel.org, Rob Herring <robh+dt@kernel.org>,
	linux-arm-kernel@lists.infradead.org,
	Marc Zyngier <maz@kernel.org>,
	Frank Rowand <frowand.list@gmail.com>,
	kvmarm@lists.cs.columbia.edu
Subject: Re: [RFC PATCH v2 17/26] KVM: arm64: Elevate Hyp mappings creation at EL2
Date: Thu, 4 Feb 2021 11:08:33 +0000	[thread overview]
Message-ID: <YBvVseNd/r8q5He1@google.com> (raw)
In-Reply-To: <20210203153138.GB18974@willie-the-truck>

On Wednesday 03 Feb 2021 at 15:31:39 (+0000), Will Deacon wrote:
> On Fri, Jan 08, 2021 at 12:15:15PM +0000, Quentin Perret wrote:
> > Previous commits have introduced infrastructure at EL2 to enable the Hyp
> > code to manage its own memory, and more specifically its stage 1 page
> > tables. However, this was preliminary work, and none of it is currently
> > in use.
> > 
> > Put all of this together by elevating the hyp mappings creation at EL2
> > when memory protection is enabled. In this case, the host kernel running
> > at EL1 still creates _temporary_ Hyp 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.
> > 
> > Signed-off-by: Quentin Perret <qperret@google.com>
> > ---
> >  arch/arm64/include/asm/kvm_mmu.h |  1 -
> >  arch/arm64/kvm/arm.c             | 62 +++++++++++++++++++++++++++++---
> >  arch/arm64/kvm/mmu.c             | 34 ++++++++++++++++++
> >  3 files changed, 92 insertions(+), 5 deletions(-)
> > 
> > diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
> > index d7ebd73ec86f..6c8466a042a9 100644
> > --- a/arch/arm64/include/asm/kvm_mmu.h
> > +++ b/arch/arm64/include/asm/kvm_mmu.h
> > @@ -309,6 +309,5 @@ static __always_inline void __load_guest_stage2(struct kvm_s2_mmu *mmu)
> >  	 */
> >  	asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_SPECULATIVE_AT));
> >  }
> > -
> >  #endif /* __ASSEMBLY__ */
> >  #endif /* __ARM64_KVM_MMU_H__ */
> > diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> > index 6af9204bcd5b..e524682c2ccf 100644
> > --- a/arch/arm64/kvm/arm.c
> > +++ b/arch/arm64/kvm/arm.c
> > @@ -1421,7 +1421,7 @@ static void cpu_prepare_hyp_mode(int cpu)
> >  	kvm_flush_dcache_to_poc(params, sizeof(*params));
> >  }
> >  
> > -static void cpu_init_hyp_mode(void)
> > +static void kvm_set_hyp_vector(void)
> 
> Please do something about the naming: now we have both cpu_set_hyp_vector()
> and kvm_set_hyp_vector()!

I'll try to find something different, but no guarantees it'll be much
better :) Suggestions welcome.

> >  {
> >  	struct kvm_nvhe_init_params *params;
> >  	struct arm_smccc_res res;
> > @@ -1439,6 +1439,11 @@ static void cpu_init_hyp_mode(void)
> >  	params = this_cpu_ptr_nvhe_sym(kvm_init_params);
> >  	arm_smccc_1_1_hvc(KVM_HOST_SMCCC_FUNC(__kvm_hyp_init), virt_to_phys(params), &res);
> >  	WARN_ON(res.a0 != SMCCC_RET_SUCCESS);
> > +}
> > +
> > +static void cpu_init_hyp_mode(void)
> > +{
> > +	kvm_set_hyp_vector();
> >  
> >  	/*
> >  	 * Disabling SSBD on a non-VHE system requires us to enable SSBS
> > @@ -1481,7 +1486,10 @@ static void cpu_set_hyp_vector(void)
> >  	struct bp_hardening_data *data = this_cpu_ptr(&bp_hardening_data);
> >  	void *vector = hyp_spectre_vector_selector[data->slot];
> >  
> > -	*this_cpu_ptr_hyp_sym(kvm_hyp_vector) = (unsigned long)vector;
> > +	if (!is_protected_kvm_enabled())
> > +		*this_cpu_ptr_hyp_sym(kvm_hyp_vector) = (unsigned long)vector;
> > +	else
> > +		kvm_call_hyp_nvhe(__pkvm_cpu_set_vector, data->slot);
> 
> *Very* minor nit, but it might be cleaner to have static inline functions
> with the same prototypes as the hypercalls, just to make the code even
> easier to read. e.g
> 
> 	if (!is_protected_kvm_enabled())
> 		_cpu_set_vector(data->slot);
> 	else
> 		kvm_call_hyp_nvhe(__pkvm_cpu_set_vector, data->slot);
> 
> you could then conceivably wrap that in a macro and avoid having the
> "is_protected_kvm_enabled()" checks explicit every time.

Happy to do this here, but are you suggesting to generalize this pattern
to other places as well?

> >  }
> >  
> >  static void cpu_hyp_reinit(void)
> > @@ -1489,13 +1497,14 @@ static void cpu_hyp_reinit(void)
> >  	kvm_init_host_cpu_context(&this_cpu_ptr_hyp_sym(kvm_host_data)->host_ctxt);
> >  
> >  	cpu_hyp_reset();
> > -	cpu_set_hyp_vector();
> >  
> >  	if (is_kernel_in_hyp_mode())
> >  		kvm_timer_init_vhe();
> >  	else
> >  		cpu_init_hyp_mode();
> >  
> > +	cpu_set_hyp_vector();
> > +
> >  	kvm_arm_init_debug();
> >  
> >  	if (vgic_present)
> > @@ -1714,13 +1723,52 @@ static int copy_cpu_ftr_regs(void)
> >  	return 0;
> >  }
> >  
> > +static int kvm_hyp_enable_protection(void)
> > +{
> > +	void *per_cpu_base = kvm_ksym_ref(kvm_arm_hyp_percpu_base);
> > +	int ret, cpu;
> > +	void *addr;
> > +
> > +	if (!is_protected_kvm_enabled())
> > +		return 0;
> 
> Maybe I'm hung up on my previous suggestion, but I feel like we shouldn't
> get here if protected kvm isn't enabled.

The alternative is to move this check next to the call site, but it
won't help much IMO.

> 
> > +	if (!hyp_mem_base)
> > +		return -ENOMEM;
> > +
> > +	addr = phys_to_virt(hyp_mem_base);
> > +	ret = create_hyp_mappings(addr, addr + hyp_mem_size - 1, PAGE_HYP);
> > +	if (ret)
> > +		return ret;
> > +
> > +	preempt_disable();
> > +	kvm_set_hyp_vector();
> > +	ret = kvm_call_hyp_nvhe(__pkvm_init, hyp_mem_base, hyp_mem_size,
> > +				num_possible_cpus(), kern_hyp_va(per_cpu_base));
> 
> Would it make sense for the __pkvm_init() hypercall to set the vector as
> well, so that we wouldn't need to disable preemption over two hypercalls?

Not sure, kvm_set_hyp_vector() itself already does multiple hypercalls,
and I need it separate from __pkvm_init for secondary CPUs.

> Failing that, maybe move the whole preempt_disable/enable sequence into
> another function.

But that I can do.

> > +	preempt_enable();
> > +	if (ret)
> > +		return ret;
> > +
> > +	free_hyp_pgds();
> > +	for_each_possible_cpu(cpu)
> > +		free_page(per_cpu(kvm_arm_hyp_stack_page, cpu));
> > +
> > +	return 0;
> > +}
> > +
> >  /**
> >   * Inits Hyp-mode on all online CPUs
> >   */
> >  static int init_hyp_mode(void)
> >  {
> >  	int cpu;
> > -	int err = 0;
> > +	int err = -ENOMEM;
> > +
> > +	/*
> > +	 * The protected Hyp-mode cannot be initialized if the memory pool
> > +	 * allocation has failed.
> > +	 */
> > +	if (is_protected_kvm_enabled() && !hyp_mem_base)
> > +		return err;
> >  
> >  	/*
> >  	 * Copy the required CPU feature register in their EL2 counterpart
> > @@ -1854,6 +1902,12 @@ static int init_hyp_mode(void)
> >  	for_each_possible_cpu(cpu)
> >  		cpu_prepare_hyp_mode(cpu);
> >  
> > +	err = kvm_hyp_enable_protection();
> > +	if (err) {
> > +		kvm_err("Failed to enable hyp memory protection: %d\n", err);
> > +		goto out_err;
> > +	}
> > +
> >  	return 0;
> >  
> >  out_err:
> > diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> > index 3cf9397dabdb..9d4c9251208e 100644
> > --- a/arch/arm64/kvm/mmu.c
> > +++ b/arch/arm64/kvm/mmu.c
> > @@ -225,15 +225,39 @@ void free_hyp_pgds(void)
> >  	if (hyp_pgtable) {
> >  		kvm_pgtable_hyp_destroy(hyp_pgtable);
> >  		kfree(hyp_pgtable);
> > +		hyp_pgtable = NULL;
> >  	}
> >  	mutex_unlock(&kvm_hyp_pgd_mutex);
> >  }
> >  
> > +static bool kvm_host_owns_hyp_mappings(void)
> > +{
> > +	if (static_branch_likely(&kvm_protected_mode_initialized))
> > +		return false;
> > +
> > +	/*
> > +	 * This can happen at boot time when __create_hyp_mappings() is called
> > +	 * after the hyp protection has been enabled, but the static key has
> > +	 * not been flipped yet.
> > +	 */
> > +	if (!hyp_pgtable && is_protected_kvm_enabled())
> > +		return false;
> > +
> > +	BUG_ON(!hyp_pgtable);
> 
> Can we fail more gracefully, e.g. by continuing without KVM?

Got any suggestion as to how that can be done? We could also just remove
that line -- that really should not happen.

Thanks!
Quentin
_______________________________________________
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: Quentin Perret <qperret@google.com>
To: Will Deacon <will@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>,
	devicetree@vger.kernel.org, kernel-team@android.com,
	Suzuki K Poulose <suzuki.poulose@arm.com>,
	android-kvm@google.com, Catalin Marinas <catalin.marinas@arm.com>,
	Fuad Tabba <tabba@google.com>,
	linux-kernel@vger.kernel.org, Rob Herring <robh+dt@kernel.org>,
	James Morse <james.morse@arm.com>,
	linux-arm-kernel@lists.infradead.org,
	Marc Zyngier <maz@kernel.org>,
	David Brazdil <dbrazdil@google.com>,
	Frank Rowand <frowand.list@gmail.com>,
	kvmarm@lists.cs.columbia.edu,
	Julien Thierry <julien.thierry.kdev@gmail.com>
Subject: Re: [RFC PATCH v2 17/26] KVM: arm64: Elevate Hyp mappings creation at EL2
Date: Thu, 4 Feb 2021 11:08:33 +0000	[thread overview]
Message-ID: <YBvVseNd/r8q5He1@google.com> (raw)
In-Reply-To: <20210203153138.GB18974@willie-the-truck>

On Wednesday 03 Feb 2021 at 15:31:39 (+0000), Will Deacon wrote:
> On Fri, Jan 08, 2021 at 12:15:15PM +0000, Quentin Perret wrote:
> > Previous commits have introduced infrastructure at EL2 to enable the Hyp
> > code to manage its own memory, and more specifically its stage 1 page
> > tables. However, this was preliminary work, and none of it is currently
> > in use.
> > 
> > Put all of this together by elevating the hyp mappings creation at EL2
> > when memory protection is enabled. In this case, the host kernel running
> > at EL1 still creates _temporary_ Hyp 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.
> > 
> > Signed-off-by: Quentin Perret <qperret@google.com>
> > ---
> >  arch/arm64/include/asm/kvm_mmu.h |  1 -
> >  arch/arm64/kvm/arm.c             | 62 +++++++++++++++++++++++++++++---
> >  arch/arm64/kvm/mmu.c             | 34 ++++++++++++++++++
> >  3 files changed, 92 insertions(+), 5 deletions(-)
> > 
> > diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
> > index d7ebd73ec86f..6c8466a042a9 100644
> > --- a/arch/arm64/include/asm/kvm_mmu.h
> > +++ b/arch/arm64/include/asm/kvm_mmu.h
> > @@ -309,6 +309,5 @@ static __always_inline void __load_guest_stage2(struct kvm_s2_mmu *mmu)
> >  	 */
> >  	asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_SPECULATIVE_AT));
> >  }
> > -
> >  #endif /* __ASSEMBLY__ */
> >  #endif /* __ARM64_KVM_MMU_H__ */
> > diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
> > index 6af9204bcd5b..e524682c2ccf 100644
> > --- a/arch/arm64/kvm/arm.c
> > +++ b/arch/arm64/kvm/arm.c
> > @@ -1421,7 +1421,7 @@ static void cpu_prepare_hyp_mode(int cpu)
> >  	kvm_flush_dcache_to_poc(params, sizeof(*params));
> >  }
> >  
> > -static void cpu_init_hyp_mode(void)
> > +static void kvm_set_hyp_vector(void)
> 
> Please do something about the naming: now we have both cpu_set_hyp_vector()
> and kvm_set_hyp_vector()!

I'll try to find something different, but no guarantees it'll be much
better :) Suggestions welcome.

> >  {
> >  	struct kvm_nvhe_init_params *params;
> >  	struct arm_smccc_res res;
> > @@ -1439,6 +1439,11 @@ static void cpu_init_hyp_mode(void)
> >  	params = this_cpu_ptr_nvhe_sym(kvm_init_params);
> >  	arm_smccc_1_1_hvc(KVM_HOST_SMCCC_FUNC(__kvm_hyp_init), virt_to_phys(params), &res);
> >  	WARN_ON(res.a0 != SMCCC_RET_SUCCESS);
> > +}
> > +
> > +static void cpu_init_hyp_mode(void)
> > +{
> > +	kvm_set_hyp_vector();
> >  
> >  	/*
> >  	 * Disabling SSBD on a non-VHE system requires us to enable SSBS
> > @@ -1481,7 +1486,10 @@ static void cpu_set_hyp_vector(void)
> >  	struct bp_hardening_data *data = this_cpu_ptr(&bp_hardening_data);
> >  	void *vector = hyp_spectre_vector_selector[data->slot];
> >  
> > -	*this_cpu_ptr_hyp_sym(kvm_hyp_vector) = (unsigned long)vector;
> > +	if (!is_protected_kvm_enabled())
> > +		*this_cpu_ptr_hyp_sym(kvm_hyp_vector) = (unsigned long)vector;
> > +	else
> > +		kvm_call_hyp_nvhe(__pkvm_cpu_set_vector, data->slot);
> 
> *Very* minor nit, but it might be cleaner to have static inline functions
> with the same prototypes as the hypercalls, just to make the code even
> easier to read. e.g
> 
> 	if (!is_protected_kvm_enabled())
> 		_cpu_set_vector(data->slot);
> 	else
> 		kvm_call_hyp_nvhe(__pkvm_cpu_set_vector, data->slot);
> 
> you could then conceivably wrap that in a macro and avoid having the
> "is_protected_kvm_enabled()" checks explicit every time.

Happy to do this here, but are you suggesting to generalize this pattern
to other places as well?

> >  }
> >  
> >  static void cpu_hyp_reinit(void)
> > @@ -1489,13 +1497,14 @@ static void cpu_hyp_reinit(void)
> >  	kvm_init_host_cpu_context(&this_cpu_ptr_hyp_sym(kvm_host_data)->host_ctxt);
> >  
> >  	cpu_hyp_reset();
> > -	cpu_set_hyp_vector();
> >  
> >  	if (is_kernel_in_hyp_mode())
> >  		kvm_timer_init_vhe();
> >  	else
> >  		cpu_init_hyp_mode();
> >  
> > +	cpu_set_hyp_vector();
> > +
> >  	kvm_arm_init_debug();
> >  
> >  	if (vgic_present)
> > @@ -1714,13 +1723,52 @@ static int copy_cpu_ftr_regs(void)
> >  	return 0;
> >  }
> >  
> > +static int kvm_hyp_enable_protection(void)
> > +{
> > +	void *per_cpu_base = kvm_ksym_ref(kvm_arm_hyp_percpu_base);
> > +	int ret, cpu;
> > +	void *addr;
> > +
> > +	if (!is_protected_kvm_enabled())
> > +		return 0;
> 
> Maybe I'm hung up on my previous suggestion, but I feel like we shouldn't
> get here if protected kvm isn't enabled.

The alternative is to move this check next to the call site, but it
won't help much IMO.

> 
> > +	if (!hyp_mem_base)
> > +		return -ENOMEM;
> > +
> > +	addr = phys_to_virt(hyp_mem_base);
> > +	ret = create_hyp_mappings(addr, addr + hyp_mem_size - 1, PAGE_HYP);
> > +	if (ret)
> > +		return ret;
> > +
> > +	preempt_disable();
> > +	kvm_set_hyp_vector();
> > +	ret = kvm_call_hyp_nvhe(__pkvm_init, hyp_mem_base, hyp_mem_size,
> > +				num_possible_cpus(), kern_hyp_va(per_cpu_base));
> 
> Would it make sense for the __pkvm_init() hypercall to set the vector as
> well, so that we wouldn't need to disable preemption over two hypercalls?

Not sure, kvm_set_hyp_vector() itself already does multiple hypercalls,
and I need it separate from __pkvm_init for secondary CPUs.

> Failing that, maybe move the whole preempt_disable/enable sequence into
> another function.

But that I can do.

> > +	preempt_enable();
> > +	if (ret)
> > +		return ret;
> > +
> > +	free_hyp_pgds();
> > +	for_each_possible_cpu(cpu)
> > +		free_page(per_cpu(kvm_arm_hyp_stack_page, cpu));
> > +
> > +	return 0;
> > +}
> > +
> >  /**
> >   * Inits Hyp-mode on all online CPUs
> >   */
> >  static int init_hyp_mode(void)
> >  {
> >  	int cpu;
> > -	int err = 0;
> > +	int err = -ENOMEM;
> > +
> > +	/*
> > +	 * The protected Hyp-mode cannot be initialized if the memory pool
> > +	 * allocation has failed.
> > +	 */
> > +	if (is_protected_kvm_enabled() && !hyp_mem_base)
> > +		return err;
> >  
> >  	/*
> >  	 * Copy the required CPU feature register in their EL2 counterpart
> > @@ -1854,6 +1902,12 @@ static int init_hyp_mode(void)
> >  	for_each_possible_cpu(cpu)
> >  		cpu_prepare_hyp_mode(cpu);
> >  
> > +	err = kvm_hyp_enable_protection();
> > +	if (err) {
> > +		kvm_err("Failed to enable hyp memory protection: %d\n", err);
> > +		goto out_err;
> > +	}
> > +
> >  	return 0;
> >  
> >  out_err:
> > diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> > index 3cf9397dabdb..9d4c9251208e 100644
> > --- a/arch/arm64/kvm/mmu.c
> > +++ b/arch/arm64/kvm/mmu.c
> > @@ -225,15 +225,39 @@ void free_hyp_pgds(void)
> >  	if (hyp_pgtable) {
> >  		kvm_pgtable_hyp_destroy(hyp_pgtable);
> >  		kfree(hyp_pgtable);
> > +		hyp_pgtable = NULL;
> >  	}
> >  	mutex_unlock(&kvm_hyp_pgd_mutex);
> >  }
> >  
> > +static bool kvm_host_owns_hyp_mappings(void)
> > +{
> > +	if (static_branch_likely(&kvm_protected_mode_initialized))
> > +		return false;
> > +
> > +	/*
> > +	 * This can happen at boot time when __create_hyp_mappings() is called
> > +	 * after the hyp protection has been enabled, but the static key has
> > +	 * not been flipped yet.
> > +	 */
> > +	if (!hyp_pgtable && is_protected_kvm_enabled())
> > +		return false;
> > +
> > +	BUG_ON(!hyp_pgtable);
> 
> Can we fail more gracefully, e.g. by continuing without KVM?

Got any suggestion as to how that can be done? We could also just remove
that line -- that really should not happen.

Thanks!
Quentin

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

  reply	other threads:[~2021-02-04 11:09 UTC|newest]

Thread overview: 295+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-08 12:14 [RFC PATCH v2 00/26] KVM/arm64: A stage 2 for the host Quentin Perret
2021-01-08 12:14 ` Quentin Perret
2021-01-08 12:14 ` Quentin Perret
2021-01-08 12:14 ` [RFC PATCH v2 01/26] arm64: lib: Annotate {clear,copy}_page() as position-independent Quentin Perret
2021-01-08 12:14   ` [RFC PATCH v2 01/26] arm64: lib: Annotate {clear, copy}_page() " Quentin Perret
2021-01-08 12:14   ` Quentin Perret
2021-01-08 12:15 ` [RFC PATCH v2 02/26] KVM: arm64: Link position-independent string routines into .hyp.text Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-01-08 12:15 ` [RFC PATCH v2 03/26] arm64: kvm: Add standalone ticket spinlock implementation for use at hyp Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-02-01 17:28   ` Will Deacon
2021-02-01 17:28     ` Will Deacon
2021-02-01 17:28     ` Will Deacon
2021-02-01 17:40     ` Quentin Perret
2021-02-01 17:40       ` Quentin Perret
2021-02-01 17:40       ` Quentin Perret
2021-01-08 12:15 ` [RFC PATCH v2 04/26] KVM: arm64: Initialize kvm_nvhe_init_params early Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-02-01 17:41   ` Will Deacon
2021-02-01 17:41     ` Will Deacon
2021-02-01 17:41     ` Will Deacon
2021-01-08 12:15 ` [RFC PATCH v2 05/26] KVM: arm64: Avoid free_page() in page-table allocator Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-02-01 17:46   ` Will Deacon
2021-02-01 17:46     ` Will Deacon
2021-02-01 17:46     ` Will Deacon
2021-01-08 12:15 ` [RFC PATCH v2 06/26] KVM: arm64: Factor memory allocation out of pgtable.c Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-02-01 18:16   ` Will Deacon
2021-02-01 18:16     ` Will Deacon
2021-02-01 18:16     ` Will Deacon
2021-02-01 18:32     ` Quentin Perret
2021-02-01 18:32       ` Quentin Perret
2021-02-01 18:32       ` Quentin Perret
2021-02-01 18:39       ` Will Deacon
2021-02-01 18:39         ` Will Deacon
2021-02-01 18:39         ` Will Deacon
2021-01-08 12:15 ` [RFC PATCH v2 07/26] KVM: arm64: Introduce a BSS section for use at Hyp Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-02-01 18:32   ` Will Deacon
2021-02-01 18:32     ` Will Deacon
2021-02-01 18:32     ` Will Deacon
2021-01-08 12:15 ` [RFC PATCH v2 08/26] KVM: arm64: Make kvm_call_hyp() a function call " Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-02-01 18:41   ` Will Deacon
2021-02-01 18:41     ` Will Deacon
2021-02-01 18:41     ` Will Deacon
2021-01-08 12:15 ` [RFC PATCH v2 09/26] KVM: arm64: Allow using kvm_nvhe_sym() in hyp code Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-02-01 18:43   ` Will Deacon
2021-02-01 18:43     ` Will Deacon
2021-02-01 18:43     ` Will Deacon
2021-01-08 12:15 ` [RFC PATCH v2 10/26] KVM: arm64: Introduce an early Hyp page allocator Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-01-08 18:15   ` kernel test robot
2021-02-01 19:00   ` Will Deacon
2021-02-01 19:00     ` Will Deacon
2021-02-01 19:00     ` Will Deacon
2021-02-02  9:44     ` Quentin Perret
2021-02-02  9:44       ` Quentin Perret
2021-02-02  9:44       ` Quentin Perret
2021-01-08 12:15 ` [RFC PATCH v2 11/26] KVM: arm64: Stub CONFIG_DEBUG_LIST at Hyp Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-02-01 19:06   ` Will Deacon
2021-02-01 19:06     ` Will Deacon
2021-02-01 19:06     ` Will Deacon
2021-02-02  9:57     ` Quentin Perret
2021-02-02  9:57       ` Quentin Perret
2021-02-02  9:57       ` Quentin Perret
2021-02-02 10:00       ` Will Deacon
2021-02-02 10:00         ` Will Deacon
2021-02-02 10:00         ` Will Deacon
2021-02-02 10:14         ` Quentin Perret
2021-02-02 10:14           ` Quentin Perret
2021-02-02 10:14           ` Quentin Perret
2021-01-08 12:15 ` [RFC PATCH v2 12/26] KVM: arm64: Introduce a Hyp buddy page allocator Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-01-08 19:21   ` kernel test robot
2021-02-02 18:13   ` Will Deacon
2021-02-02 18:13     ` Will Deacon
2021-02-02 18:13     ` Will Deacon
2021-02-03 18:33     ` Quentin Perret
2021-02-03 18:33       ` Quentin Perret
2021-02-03 18:33       ` Quentin Perret
2021-02-04 14:31       ` Will Deacon
2021-02-04 14:31         ` Will Deacon
2021-02-04 14:31         ` Will Deacon
2021-02-04 14:52         ` Quentin Perret
2021-02-04 14:52           ` Quentin Perret
2021-02-04 14:52           ` Quentin Perret
2021-02-04 17:48           ` Will Deacon
2021-02-04 17:48             ` Will Deacon
2021-02-04 17:48             ` Will Deacon
2021-02-04 18:01             ` Quentin Perret
2021-02-04 18:01               ` Quentin Perret
2021-02-04 18:01               ` Quentin Perret
2021-02-04 18:13               ` Will Deacon
2021-02-04 18:13                 ` Will Deacon
2021-02-04 18:13                 ` Will Deacon
2021-02-04 18:24                 ` Quentin Perret
2021-02-04 18:24                   ` Quentin Perret
2021-02-04 18:24                   ` Quentin Perret
2021-02-04 18:19         ` Quentin Perret
2021-02-04 18:19           ` Quentin Perret
2021-02-04 18:19           ` Quentin Perret
2021-02-04 18:24           ` Will Deacon
2021-02-04 18:24             ` Will Deacon
2021-02-04 18:24             ` Will Deacon
2021-02-04 18:32             ` Quentin Perret
2021-02-04 18:32               ` Quentin Perret
2021-02-04 18:32               ` Quentin Perret
2021-01-08 12:15 ` [RFC PATCH v2 13/26] KVM: arm64: Enable access to sanitized CPU features at EL2 Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-01-13 11:33   ` Marc Zyngier
2021-01-13 11:33     ` Marc Zyngier
2021-01-13 11:33     ` Marc Zyngier
2021-01-13 14:23     ` Quentin Perret
2021-01-13 14:23       ` Quentin Perret
2021-01-13 14:23       ` Quentin Perret
2021-01-13 14:35       ` Quentin Perret
2021-01-13 14:35         ` Quentin Perret
2021-01-13 14:35         ` Quentin Perret
2021-01-13 17:27         ` Marc Zyngier
2021-01-13 17:27           ` Marc Zyngier
2021-01-13 17:27           ` Marc Zyngier
2021-01-13 18:28           ` Quentin Perret
2021-01-13 18:28             ` Quentin Perret
2021-01-13 18:28             ` Quentin Perret
2021-01-08 12:15 ` [RFC PATCH v2 14/26] KVM: arm64: Factor out vector address calculation Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-02-02 18:24   ` Will Deacon
2021-02-02 18:24     ` Will Deacon
2021-02-02 18:24     ` Will Deacon
2021-01-08 12:15 ` [RFC PATCH v2 15/26] of/fdt: Introduce early_init_dt_add_memory_hyp() Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-01-08 14:54   ` kernel test robot
2021-01-08 18:58   ` kernel test robot
2021-01-11 14:45   ` Rob Herring
2021-01-11 14:45     ` Rob Herring
2021-01-11 14:45     ` Rob Herring
2021-01-12  9:51     ` Quentin Perret
2021-01-12  9:51       ` Quentin Perret
2021-01-12  9:51       ` Quentin Perret
2021-01-12 14:10       ` Rob Herring
2021-01-12 14:10         ` Rob Herring
2021-01-12 14:10         ` Rob Herring
2021-01-12 14:26         ` Quentin Perret
2021-01-12 14:26           ` Quentin Perret
2021-01-12 14:26           ` Quentin Perret
2021-01-12 15:53           ` Rob Herring
2021-01-12 15:53             ` Rob Herring
2021-01-12 15:53             ` Rob Herring
2021-01-12 16:15             ` Quentin Perret
2021-01-12 16:15               ` Quentin Perret
2021-01-12 16:15               ` Quentin Perret
2021-01-12 16:45               ` Rob Herring
2021-01-12 16:45                 ` Rob Herring
2021-01-12 16:45                 ` Rob Herring
2021-01-12 16:50                 ` Quentin Perret
2021-01-12 16:50                   ` Quentin Perret
2021-01-12 16:50                   ` Quentin Perret
2021-01-15 11:49                   ` Quentin Perret
2021-01-15 11:49                     ` Quentin Perret
2021-01-15 11:49                     ` Quentin Perret
2021-01-08 12:15 ` [RFC PATCH v2 16/26] KVM: arm64: Prepare Hyp memory protection Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-02-03 14:37   ` Will Deacon
2021-02-03 14:37     ` Will Deacon
2021-02-03 14:37     ` Will Deacon
2021-02-04 10:47     ` Quentin Perret
2021-02-04 10:47       ` Quentin Perret
2021-02-04 10:47       ` Quentin Perret
2021-02-05 17:56       ` Will Deacon
2021-02-05 17:56         ` Will Deacon
2021-02-05 17:56         ` Will Deacon
2021-02-09 10:00       ` Quentin Perret
2021-02-09 10:00         ` Quentin Perret
2021-02-09 10:00         ` Quentin Perret
2021-02-09 12:23         ` Will Deacon
2021-02-09 12:23           ` Will Deacon
2021-02-09 12:23           ` Will Deacon
2021-02-19 18:32     ` Sean Christopherson
2021-02-19 18:32       ` Sean Christopherson
2021-02-19 18:32       ` Sean Christopherson
2021-02-22 11:04       ` Quentin Perret
2021-02-22 11:04         ` Quentin Perret
2021-02-22 11:04         ` Quentin Perret
2021-01-08 12:15 ` [RFC PATCH v2 17/26] KVM: arm64: Elevate Hyp mappings creation at EL2 Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-02-03 15:31   ` Will Deacon
2021-02-03 15:31     ` Will Deacon
2021-02-03 15:31     ` Will Deacon
2021-02-04 11:08     ` Quentin Perret [this message]
2021-02-04 11:08       ` Quentin Perret
2021-02-04 11:08       ` Quentin Perret
2021-02-05 18:01       ` Will Deacon
2021-02-05 18:01         ` Will Deacon
2021-02-05 18:01         ` Will Deacon
2021-01-08 12:15 ` [RFC PATCH v2 18/26] KVM: arm64: Use kvm_arch for stage 2 pgtable Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-02-03 15:34   ` Will Deacon
2021-02-03 15:34     ` Will Deacon
2021-02-03 15:34     ` Will Deacon
2021-01-08 12:15 ` [RFC PATCH v2 19/26] KVM: arm64: Use kvm_arch in kvm_s2_mmu Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-02-03 15:38   ` Will Deacon
2021-02-03 15:38     ` Will Deacon
2021-02-03 15:38     ` Will Deacon
2021-01-08 12:15 ` [RFC PATCH v2 20/26] KVM: arm64: Set host stage 2 using kvm_nvhe_init_params Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-02-03 16:05   ` Will Deacon
2021-02-03 16:05     ` Will Deacon
2021-02-03 16:05     ` Will Deacon
2021-01-08 12:15 ` [RFC PATCH v2 21/26] KVM: arm64: Refactor kvm_arm_setup_stage2() Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-02-03 15:53   ` Will Deacon
2021-02-03 15:53     ` Will Deacon
2021-02-03 15:53     ` Will Deacon
2021-02-04 14:07     ` Quentin Perret
2021-02-04 14:07       ` Quentin Perret
2021-02-04 14:07       ` Quentin Perret
2021-01-08 12:15 ` [RFC PATCH v2 22/26] KVM: arm64: Refactor __load_guest_stage2() Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-02-03 15:54   ` Will Deacon
2021-02-03 15:54     ` Will Deacon
2021-02-03 15:54     ` Will Deacon
2021-01-08 12:15 ` [RFC PATCH v2 23/26] KVM: arm64: Refactor __populate_fault_info() Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-02-03 15:58   ` Will Deacon
2021-02-03 15:58     ` Will Deacon
2021-02-03 15:58     ` Will Deacon
2021-02-04 14:18     ` Quentin Perret
2021-02-04 14:18       ` Quentin Perret
2021-02-04 14:18       ` Quentin Perret
2021-01-08 12:15 ` [RFC PATCH v2 24/26] KVM: arm64: Make memcache anonymous in pgtable allocator Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-02-03 15:59   ` Will Deacon
2021-02-03 15:59     ` Will Deacon
2021-02-03 15:59     ` Will Deacon
2021-02-04 14:24     ` Quentin Perret
2021-02-04 14:24       ` Quentin Perret
2021-02-04 14:24       ` Quentin Perret
2021-02-04 14:36       ` Will Deacon
2021-02-04 14:36         ` Will Deacon
2021-02-04 14:36         ` Will Deacon
2021-01-08 12:15 ` [RFC PATCH v2 25/26] KVM: arm64: Reserve memory for host stage 2 Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-01-08 12:15 ` [RFC PATCH v2 26/26] KVM: arm64: Wrap the host with a " Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-01-08 12:15   ` Quentin Perret
2021-02-03 16:11   ` Will Deacon
2021-02-03 16:11     ` Will Deacon
2021-02-03 16:11     ` Will Deacon
2021-02-04 14:26     ` Quentin Perret
2021-02-04 14:26       ` Quentin Perret
2021-02-04 14:26       ` Quentin Perret
2021-02-04 14:37       ` Will Deacon
2021-02-04 14:37         ` Will Deacon
2021-02-04 14:37         ` Will Deacon
2021-02-17 16:27 ` [RFC PATCH v2 00/26] KVM/arm64: A stage 2 for the host Mate Toth-Pal
2021-02-17 16:27   ` Mate Toth-Pal
2021-02-17 16:27   ` Mate Toth-Pal
2021-02-17 17:24   ` Quentin Perret
2021-02-17 17:24     ` Quentin Perret
2021-02-17 17:24     ` Quentin Perret
2021-02-19 17:54 ` Sean Christopherson
2021-02-19 17:54   ` Sean Christopherson
2021-02-19 17:54   ` Sean Christopherson
2021-02-19 17:57   ` Quentin Perret
2021-02-19 17:57     ` Quentin Perret
2021-02-19 17:57     ` 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=YBvVseNd/r8q5He1@google.com \
    --to=qperret@google.com \
    --cc=android-kvm@google.com \
    --cc=catalin.marinas@arm.com \
    --cc=dbrazdil@google.com \
    --cc=devicetree@vger.kernel.org \
    --cc=frowand.list@gmail.com \
    --cc=james.morse@arm.com \
    --cc=julien.thierry.kdev@gmail.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=mark.rutland@arm.com \
    --cc=maz@kernel.org \
    --cc=robh+dt@kernel.org \
    --cc=suzuki.poulose@arm.com \
    --cc=tabba@google.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.