mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Marc Zyngier <maz@kernel.org>
To: "Lorenzo Stoakes (ARM)" <ljs@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>,
	Will Deacon <will@kernel.org>, Oliver Upton <oupton@kernel.org>,
	Fuad Tabba <tabba@google.com>, Joey Gouly <joey.gouly@arm.com>,
	Steffen Eiden <seiden@linux.ibm.com>,
	Suzuki K Poulose <suzuki.poulose@arm.com>,
	Zenghui Yu <yuzenghui@huawei.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Jonathan Corbet <corbet@lwn.net>,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, kvmarm@lists.linux.dev,
	kvm@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kselftest@vger.kernel.org,
	Jack Thomson <jackabt@amazon.com>,
	Jack Thomson <jackabt.amazon@gmail.com>,
	Alexandru Elisei <alexandru.elisei@arm.com>,
	Vincent Donnefort <vdonnefort@google.com>,
	"Aneesh Kumar K.V" <aneesh.kumar@kernel.org>,
	Sean Christopherson <seanjc@google.com>,
	Claudio Imbrenda <imbrenda@linux.ibm.com>,
	Leo Soares Passos <Leo.Bras@arm.com>
Subject: Re: [PATCH 1/8] KVM: arm64: Propagate and use esr in s2fd when handling guest aborts
Date: Thu, 10 Sep 2026 09:39:58 +0100	[thread overview]
Message-ID: <86wlst7b4x.wl-maz@kernel.org> (raw)
In-Reply-To: <20260825-kvm-arm-prefault-v1-1-befe8947702e@kernel.org>

On Tue, 25 Aug 2026 17:00:35 +0100,
"Lorenzo Stoakes (ARM)" <ljs@kernel.org> wrote:
> 
> kvm_handle_guest_abort() establishes a kvm_s2_fault_desc data structure,
> s2fd, to store and propagate state to either pkvm_mem_abort(), gmem_abort()
> or user_mem_abort() handlers.
> 
> Each of these, however, examines the Exception Syndrome Register (ESR) via
> s2fd->vcpu.
> 
> Introduce an s2fd->esr field to abstract this and propagate it to callers.
> 
> The value of this (beyond refactoring) is to be able to later generate
> faults with a synthetic esr, specifically to implement stage 2 page table
> pre-faulting.
> 
> Abstract esr-specific predicates and helpers to the esr.h header and either
> have vcpu wrappers call these, or eliminate them if they are not used
> elsewhere.
> 
> Provide kvm_s2_fault_is_[write,exec,perm]() helpers for convenience.
> 
> Since kvm_s2_fault_map() either sets perm_fault_granule to the permission
> fault granule or 0 if not a permission fault, implement
> kvm_s2_perm_fault_granule() to do this directly.
> 
> Abort handlers which use kvm_s2_fault_desc - gmem_abort() and
> user_mem_abort() - now only reference s2fd->esr and do not look it up in
> any other way, which makes it safe to pass a synthetic s2fd->esr value to
> these functions.

Please split this. ESR helpers in one patch, hacking the MMU code to
use it in another, s2fd->esr stuff last.

> 
> No functional change intended.
> 
> Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
> ---
>  arch/arm64/include/asm/esr.h         | 129 +++++++++++++++++++++++++----------
>  arch/arm64/include/asm/kvm_emulate.h |  52 ++++----------
>  arch/arm64/kvm/mmu.c                 |  80 +++++++++++++---------
>  3 files changed, 156 insertions(+), 105 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
> index f816f5d77f1a..162e90c832e9 100644
> --- a/arch/arm64/include/asm/esr.h
> +++ b/arch/arm64/include/asm/esr.h
> @@ -437,6 +437,32 @@
>  #ifndef __ASSEMBLER__
>  #include <asm/types.h>
>  
> +static inline u8 esr_trap_get_class(unsigned long esr)

nit: there is no notion of trap here. This is simply extracting the EC
from the ESR. My personal (and wholly unreliable) taste would be to go
for something like esr_get_ec().

I appreciate that you are simply propagating the names used in KVM,
but they were pretty poor the first place, and have only been kept to
avoid churn.

Also, 'inline' is a bit of a problem given that the callers are
__always_inline for good reasons (see 5c37f1ae1c3358).

> +{
> +	return ESR_ELx_EC(esr);
> +}
> +
> +static inline bool esr_trap_is_iabt(unsigned long esr)
> +{
> +	return esr_trap_get_class(esr) == ESR_ELx_EC_IABT_LOW;
> +}
> +
> +static inline bool esr_abt_is_s1ptw(unsigned long esr)
> +{
> +	return esr & ESR_ELx_S1PTW;
> +}
> +
> +/* Always check for S1PTW *before* using this. */
> +static inline bool esr_dabt_is_write(unsigned long esr)
> +{
> +	return esr & ESR_ELx_WNR;
> +}
> +
> +static inline bool esr_dabt_is_cm(unsigned long esr)
> +{
> +	return esr & ESR_ELx_CM;
> +}
> +
>  static inline unsigned long esr_brk_comment(unsigned long esr)
>  {
>  	return esr & ESR_ELx_BRK64_ISS_COMMENT_MASK;
> @@ -460,75 +486,104 @@ static inline bool esr_is_ubsan_brk(unsigned long esr)
>  	return (esr_brk_comment(esr) & ~UBSAN_BRK_MASK) == UBSAN_BRK_IMM;
>  }
>  
> +static inline u8 esr_fsc_get_fault(unsigned long esr)
> +{
> +	return esr & ESR_ELx_FSC;
> +}
> +
>  static inline bool esr_fsc_is_translation_fault(unsigned long esr)
>  {
> -	esr = esr & ESR_ELx_FSC;
> +	const u8 fault = esr_fsc_get_fault(esr);
>  
> -	return (esr == ESR_ELx_FSC_FAULT_L(3)) ||
> -	       (esr == ESR_ELx_FSC_FAULT_L(2)) ||
> -	       (esr == ESR_ELx_FSC_FAULT_L(1)) ||
> -	       (esr == ESR_ELx_FSC_FAULT_L(0)) ||
> -	       (esr == ESR_ELx_FSC_FAULT_L(-1));
> +	return (fault == ESR_ELx_FSC_FAULT_L(3)) ||
> +	       (fault == ESR_ELx_FSC_FAULT_L(2)) ||
> +	       (fault == ESR_ELx_FSC_FAULT_L(1)) ||
> +	       (fault == ESR_ELx_FSC_FAULT_L(0)) ||
> +	       (fault == ESR_ELx_FSC_FAULT_L(-1));

I really think we could do without this sort of churn.

>  }
>  
>  static inline bool esr_fsc_is_permission_fault(unsigned long esr)
>  {
> -	esr = esr & ESR_ELx_FSC;
> +	const u8 fault = esr_fsc_get_fault(esr);
>  
> -	return (esr == ESR_ELx_FSC_PERM_L(3)) ||
> -	       (esr == ESR_ELx_FSC_PERM_L(2)) ||
> -	       (esr == ESR_ELx_FSC_PERM_L(1)) ||
> -	       (esr == ESR_ELx_FSC_PERM_L(0));
> +	return (fault == ESR_ELx_FSC_PERM_L(3)) ||
> +	       (fault == ESR_ELx_FSC_PERM_L(2)) ||
> +	       (fault == ESR_ELx_FSC_PERM_L(1)) ||
> +	       (fault == ESR_ELx_FSC_PERM_L(0));
>  }
>  
>  static inline bool esr_fsc_is_access_flag_fault(unsigned long esr)
>  {
> -	esr = esr & ESR_ELx_FSC;
> +	const u8 fault = esr_fsc_get_fault(esr);
>  
> -	return (esr == ESR_ELx_FSC_ACCESS_L(3)) ||
> -	       (esr == ESR_ELx_FSC_ACCESS_L(2)) ||
> -	       (esr == ESR_ELx_FSC_ACCESS_L(1)) ||
> -	       (esr == ESR_ELx_FSC_ACCESS_L(0));
> +	return (fault == ESR_ELx_FSC_ACCESS_L(3)) ||
> +	       (fault == ESR_ELx_FSC_ACCESS_L(2)) ||
> +	       (fault == ESR_ELx_FSC_ACCESS_L(1)) ||
> +	       (fault == ESR_ELx_FSC_ACCESS_L(0));
>  }
>  
>  static inline bool esr_fsc_is_excl_atomic_fault(unsigned long esr)
>  {
> -	esr = esr & ESR_ELx_FSC;
> -
> -	return esr == ESR_ELx_FSC_EXCL_ATOMIC;
> +	return esr_fsc_get_fault(esr) == ESR_ELx_FSC_EXCL_ATOMIC;
>  }
>  
>  static inline bool esr_fsc_is_addr_sz_fault(unsigned long esr)
>  {
> -	esr &= ESR_ELx_FSC;
> +	const u8 fault = esr_fsc_get_fault(esr);
> +
> +	return (fault == ESR_ELx_FSC_ADDRSZ_L(3)) ||
> +	       (fault == ESR_ELx_FSC_ADDRSZ_L(2)) ||
> +	       (fault == ESR_ELx_FSC_ADDRSZ_L(1)) ||
> +	       (fault == ESR_ELx_FSC_ADDRSZ_L(0)) ||
> +	       (fault == ESR_ELx_FSC_ADDRSZ_L(-1));
> +}
> +
> +static inline bool esr_abt_is_exec_fault(unsigned long esr)
> +{
> +	return esr_trap_is_iabt(esr) && !esr_abt_is_s1ptw(esr);
> +}
>  
> -	return (esr == ESR_ELx_FSC_ADDRSZ_L(3))	||
> -	       (esr == ESR_ELx_FSC_ADDRSZ_L(2))	||
> -	       (esr == ESR_ELx_FSC_ADDRSZ_L(1)) ||
> -	       (esr == ESR_ELx_FSC_ADDRSZ_L(0))	||
> -	       (esr == ESR_ELx_FSC_ADDRSZ_L(-1));
> +static inline bool esr_abt_is_sea(unsigned long esr)
> +{
> +	const u8 fault = esr_fsc_get_fault(esr);
> +
> +	switch (fault) {
> +	case ESR_ELx_FSC_EXTABT:
> +	case ESR_ELx_FSC_SEA_TTW(-1) ... ESR_ELx_FSC_SEA_TTW(3):
> +	case ESR_ELx_FSC_SECC:
> +	case ESR_ELx_FSC_SECC_TTW(-1) ... ESR_ELx_FSC_SECC_TTW(3):
> +		return true;
> +	default:
> +		return false;
> +	}
> +}
> +
> +/* Not valid for negative levels. */
> +static inline u64 esr_fsc_get_level(unsigned long esr)
> +{
> +	return esr & ESR_ELx_FSC_LEVEL;
>  }

If that's such an unreliable helper, why is it exposed to everyone
instead of being kept local to the single caller?

>  
>  static inline bool esr_fsc_is_sea_ttw(unsigned long esr)
>  {
> -	esr = esr & ESR_ELx_FSC;
> +	const u8 fault = esr_fsc_get_fault(esr);
>  
> -	return (esr == ESR_ELx_FSC_SEA_TTW(3)) ||
> -	       (esr == ESR_ELx_FSC_SEA_TTW(2)) ||
> -	       (esr == ESR_ELx_FSC_SEA_TTW(1)) ||
> -	       (esr == ESR_ELx_FSC_SEA_TTW(0)) ||
> -	       (esr == ESR_ELx_FSC_SEA_TTW(-1));
> +	return (fault == ESR_ELx_FSC_SEA_TTW(3)) ||
> +	       (fault == ESR_ELx_FSC_SEA_TTW(2)) ||
> +	       (fault == ESR_ELx_FSC_SEA_TTW(1)) ||
> +	       (fault == ESR_ELx_FSC_SEA_TTW(0)) ||
> +	       (fault == ESR_ELx_FSC_SEA_TTW(-1));
>  }
>  
>  static inline bool esr_fsc_is_secc_ttw(unsigned long esr)
>  {
> -	esr = esr & ESR_ELx_FSC;
> +	const u8 fault = esr_fsc_get_fault(esr);
>  
> -	return (esr == ESR_ELx_FSC_SECC_TTW(3)) ||
> -	       (esr == ESR_ELx_FSC_SECC_TTW(2)) ||
> -	       (esr == ESR_ELx_FSC_SECC_TTW(1)) ||
> -	       (esr == ESR_ELx_FSC_SECC_TTW(0)) ||
> -	       (esr == ESR_ELx_FSC_SECC_TTW(-1));
> +	return (fault == ESR_ELx_FSC_SECC_TTW(3)) ||
> +	       (fault == ESR_ELx_FSC_SECC_TTW(2)) ||
> +	       (fault == ESR_ELx_FSC_SECC_TTW(1)) ||
> +	       (fault == ESR_ELx_FSC_SECC_TTW(0)) ||
> +	       (fault == ESR_ELx_FSC_SECC_TTW(-1));
>  }
>  
>  /* Indicate whether ESR.EC==0x1A is for an ERETAx instruction */
> diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
> index a3c1928bdf74..811d7a68a9f9 100644
> --- a/arch/arm64/include/asm/kvm_emulate.h
> +++ b/arch/arm64/include/asm/kvm_emulate.h
> @@ -411,18 +411,13 @@ static __always_inline int kvm_vcpu_dabt_get_rd(const struct kvm_vcpu *vcpu)
>  
>  static __always_inline bool kvm_vcpu_abt_iss1tw(const struct kvm_vcpu *vcpu)
>  {
> -	return !!(kvm_vcpu_get_esr(vcpu) & ESR_ELx_S1PTW);
> +	return esr_abt_is_s1ptw(kvm_vcpu_get_esr(vcpu));
>  }
>  
>  /* Always check for S1PTW *before* using this. */
>  static __always_inline bool kvm_vcpu_dabt_iswrite(const struct kvm_vcpu *vcpu)
>  {
> -	return kvm_vcpu_get_esr(vcpu) & ESR_ELx_WNR;
> -}
> -
> -static inline bool kvm_vcpu_dabt_is_cm(const struct kvm_vcpu *vcpu)
> -{
> -	return !!(kvm_vcpu_get_esr(vcpu) & ESR_ELx_CM);
> +	return esr_dabt_is_write(kvm_vcpu_get_esr(vcpu));
>  }
>  
>  static __always_inline unsigned int kvm_vcpu_dabt_get_as(const struct kvm_vcpu *vcpu)
> @@ -438,17 +433,12 @@ static __always_inline bool kvm_vcpu_trap_il_is32bit(const struct kvm_vcpu *vcpu
>  
>  static __always_inline u8 kvm_vcpu_trap_get_class(const struct kvm_vcpu *vcpu)
>  {
> -	return ESR_ELx_EC(kvm_vcpu_get_esr(vcpu));
> +	return esr_trap_get_class(kvm_vcpu_get_esr(vcpu));
>  }
>  
>  static inline bool kvm_vcpu_trap_is_iabt(const struct kvm_vcpu *vcpu)
>  {
> -	return kvm_vcpu_trap_get_class(vcpu) == ESR_ELx_EC_IABT_LOW;
> -}
> -
> -static inline bool kvm_vcpu_trap_is_exec_fault(const struct kvm_vcpu *vcpu)
> -{
> -	return kvm_vcpu_trap_is_iabt(vcpu) && !kvm_vcpu_abt_iss1tw(vcpu);
> +	return esr_trap_is_iabt(kvm_vcpu_get_esr(vcpu));
>  }
>  
>  static __always_inline u8 kvm_vcpu_trap_get_fault(const struct kvm_vcpu *vcpu)
> @@ -468,26 +458,9 @@ bool kvm_vcpu_trap_is_translation_fault(const struct kvm_vcpu *vcpu)
>  	return esr_fsc_is_translation_fault(kvm_vcpu_get_esr(vcpu));
>  }
>  
> -static inline
> -u64 kvm_vcpu_trap_get_perm_fault_granule(const struct kvm_vcpu *vcpu)
> -{
> -	unsigned long esr = kvm_vcpu_get_esr(vcpu);
> -
> -	BUG_ON(!esr_fsc_is_permission_fault(esr));
> -	return BIT(ARM64_HW_PGTABLE_LEVEL_SHIFT(esr & ESR_ELx_FSC_LEVEL));
> -}
> -
>  static __always_inline bool kvm_vcpu_abt_issea(const struct kvm_vcpu *vcpu)
>  {
> -	switch (kvm_vcpu_trap_get_fault(vcpu)) {
> -	case ESR_ELx_FSC_EXTABT:
> -	case ESR_ELx_FSC_SEA_TTW(-1) ... ESR_ELx_FSC_SEA_TTW(3):
> -	case ESR_ELx_FSC_SECC:
> -	case ESR_ELx_FSC_SECC_TTW(-1) ... ESR_ELx_FSC_SECC_TTW(3):
> -		return true;
> -	default:
> -		return false;
> -	}
> +	return esr_abt_is_sea(kvm_vcpu_get_esr(vcpu));
>  }
>  
>  static __always_inline int kvm_vcpu_sys_get_rt(struct kvm_vcpu *vcpu)
> @@ -496,9 +469,9 @@ static __always_inline int kvm_vcpu_sys_get_rt(struct kvm_vcpu *vcpu)
>  	return ESR_ELx_SYS64_ISS_RT(esr);
>  }
>  
> -static inline bool kvm_is_write_fault(struct kvm_vcpu *vcpu)
> +static inline bool esr_abt_is_write_fault(unsigned long esr)
>  {
> -	if (kvm_vcpu_abt_iss1tw(vcpu)) {
> +	if (esr_abt_is_s1ptw(esr)) {
>  		/*
>  		 * Only a permission fault on a S1PTW should be
>  		 * considered as a write. Otherwise, page tables baked
> @@ -511,13 +484,18 @@ static inline bool kvm_is_write_fault(struct kvm_vcpu *vcpu)
>  		 * first), then a permission fault to allow the flags
>  		 * to be set.
>  		 */
> -		return kvm_vcpu_trap_is_permission_fault(vcpu);
> +		return esr_fsc_is_permission_fault(esr);
>  	}
>  
> -	if (kvm_vcpu_trap_is_iabt(vcpu))
> +	if (esr_trap_is_iabt(esr))
>  		return false;
>  
> -	return kvm_vcpu_dabt_iswrite(vcpu);
> +	return esr_dabt_is_write(esr);
> +}
> +
> +static inline bool kvm_is_write_fault(struct kvm_vcpu *vcpu)
> +{
> +	return esr_abt_is_write_fault(kvm_vcpu_get_esr(vcpu));
>  }
>  
>  static inline unsigned long kvm_vcpu_get_mpidr_aff(struct kvm_vcpu *vcpu)
> diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
> index 74e7e7f7564c..30d605e87b01 100644
> --- a/arch/arm64/kvm/mmu.c
> +++ b/arch/arm64/kvm/mmu.c
> @@ -1603,12 +1603,38 @@ struct kvm_s2_fault_desc {
>  	struct kvm_s2_trans	*nested;
>  	struct kvm_memory_slot	*memslot;
>  	unsigned long		hva;
> +	unsigned long		esr;
>  };
>  
> +static bool kvm_s2_fault_is_perm(const struct kvm_s2_fault_desc *s2fd)
> +{
> +	return esr_fsc_is_permission_fault(s2fd->esr);
> +}
> +
> +static bool kvm_s2_fault_is_exec(const struct kvm_s2_fault_desc *s2fd)
> +{
> +	return esr_abt_is_exec_fault(s2fd->esr);
> +}
> +
> +static bool kvm_s2_fault_is_write(const struct kvm_s2_fault_desc *s2fd)
> +{
> +	return esr_abt_is_write_fault(s2fd->esr);
> +}
> +
> +static u64 kvm_s2_perm_fault_granule(const struct kvm_s2_fault_desc *s2fd)
> +{
> +	u64 level;
> +
> +	if (!kvm_s2_fault_is_perm(s2fd))
> +		return 0;
> +	level = esr_fsc_get_level(s2fd->esr);
> +	return BIT(ARM64_HW_PGTABLE_LEVEL_SHIFT(level));
> +}
> +
>  static int gmem_abort(const struct kvm_s2_fault_desc *s2fd)
>  {
>  	bool write_fault, exec_fault;
> -	bool perm_fault = kvm_vcpu_trap_is_permission_fault(s2fd->vcpu);
> +	const bool perm_fault = kvm_s2_fault_is_perm(s2fd);

Please don't randomly introduce const local variables. I understand
the benefit, but *if* we want to go down that road, then we do it for
all the predicates, as a separate series, because this obviously
applies to {exec,write}_fault as well.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.

  reply	other threads:[~2026-09-10  8:40 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-25 16:00 [PATCH 0/8] KVM: arm64: Add KVM_PRE_FAULT_MEMORY support Lorenzo Stoakes (ARM)
2026-08-25 16:00 ` [PATCH 1/8] KVM: arm64: Propagate and use esr in s2fd when handling guest aborts Lorenzo Stoakes (ARM)
2026-09-10  8:39   ` Marc Zyngier [this message]
2026-09-10  9:04     ` Lorenzo Stoakes (ARM)
2026-08-25 16:00 ` [PATCH 2/8] KVM: arm64: Propagate and use mmu " Lorenzo Stoakes (ARM)
2026-08-25 16:00 ` [PATCH 3/8] KVM: arm64: Propagate and use kvm_s2_fault_result on S2 fault Lorenzo Stoakes (ARM)
2026-09-10  8:49   ` Marc Zyngier
2026-09-10  9:00     ` Lorenzo Stoakes (ARM)
2026-08-25 16:00 ` [PATCH 4/8] KVM: arm64: Pass walk flags to kvm_pgtable_get_leaf() Lorenzo Stoakes (ARM)
2026-08-25 16:00 ` [PATCH 5/8] KVM: arm64: Implement KVM_PRE_FAULT_MEMORY Lorenzo Stoakes (ARM)
2026-09-10 10:02   ` Marc Zyngier
2026-09-10 15:32     ` Lorenzo Stoakes (ARM)
2026-08-25 16:00 ` [PATCH 6/8] KVM: selftests: Enable pre_fault_memory_test for arm64 Lorenzo Stoakes (ARM)
2026-09-10 18:52   ` Fuad Tabba
2026-08-25 16:00 ` [PATCH 7/8] KVM: selftests: Add option for different backing in pre-fault tests Lorenzo Stoakes (ARM)
2026-08-25 16:00 ` [PATCH 8/8] KVM: selftests: Add nested pre-fault test for arm64 Lorenzo Stoakes (ARM)
2026-09-10 18:57   ` Fuad Tabba
2026-09-11  9:21     ` Lorenzo Stoakes (ARM)
2026-09-11  6:30   ` Itaru Kitayama
2026-09-11  9:32     ` Lorenzo Stoakes (ARM)
2026-09-11 12:42       ` Wei-Lin Chang
2026-09-11 15:44         ` Lorenzo Stoakes (ARM)
2026-09-10 18:44 ` [PATCH 0/8] KVM: arm64: Add KVM_PRE_FAULT_MEMORY support Fuad Tabba
2026-09-11  9:16   ` Lorenzo Stoakes (ARM)

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=86wlst7b4x.wl-maz@kernel.org \
    --to=maz@kernel.org \
    --cc=Leo.Bras@arm.com \
    --cc=alexandru.elisei@arm.com \
    --cc=aneesh.kumar@kernel.org \
    --cc=catalin.marinas@arm.com \
    --cc=corbet@lwn.net \
    --cc=imbrenda@linux.ibm.com \
    --cc=jackabt.amazon@gmail.com \
    --cc=jackabt@amazon.com \
    --cc=joey.gouly@arm.com \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.linux.dev \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=ljs@kernel.org \
    --cc=oupton@kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=seanjc@google.com \
    --cc=seiden@linux.ibm.com \
    --cc=suzuki.poulose@arm.com \
    --cc=tabba@google.com \
    --cc=vdonnefort@google.com \
    --cc=will@kernel.org \
    --cc=yuzenghui@huawei.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®