From: Steffen Eiden <seiden@linux.ibm.com>
To: kvm@vger.kernel.org, kvmarm@lists.linux.dev,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org
Cc: Alexander Gordeev <agordeev@linux.ibm.com>,
Andreas Grapentin <gra@linux.ibm.com>,
Arnd Bergmann <arnd@arndb.de>,
Catalin Marinas <catalin.marinas@arm.com>,
Christian Borntraeger <borntraeger@linux.ibm.com>,
Claudio Imbrenda <imbrenda@linux.ibm.com>,
David Hildenbrand <david@kernel.org>,
Friedrich Welter <fritz@linux.ibm.com>,
Fuad Tabba <tabba@google.com>, Gautam Gala <ggala@linux.ibm.com>,
Hariharan Mari <hari55@linux.ibm.com>,
Heiko Carstens <hca@linux.ibm.com>,
Hendrik Brueckner <brueckner@linux.ibm.com>,
Ilya Leoshkevich <iii@linux.ibm.com>,
Janosch Frank <frankja@linux.ibm.com>,
Joey Gouly <joey.gouly@arm.com>, Marc Zyngier <maz@kernel.org>,
Nico Boehr <nrb@linux.ibm.com>,
Nina Schoetterl-Glausch <oss@nina.schoetterlglausch.eu>,
Oliver Upton <oupton@kernel.org>,
Paolo Bonzini <pbonzini@redhat.com>,
Sean Christopherson <seanjc@google.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Sven Schnelle <svens@linux.ibm.com>,
Ulrich Weigand <Ulrich.Weigand@de.ibm.com>,
Vasily Gorbik <gor@linux.ibm.com>, Will Deacon <will@kernel.org>,
Zenghui Yu <yuzenghui@huawei.com>
Subject: [PATCH v6 18/33] KVM: s390: Prepare gmap for a second KVM implementation
Date: Wed, 12 Aug 2026 17:36:14 +0200 [thread overview]
Message-ID: <20260812153631.3376090-19-seiden@linux.ibm.com> (raw)
In-Reply-To: <20260812153631.3376090-1-seiden@linux.ibm.com>
Refactor gmap code such that a second s390 (host) KVM implementation can
use the gmap code as well. Move mmu code from s390 to gmap so the other
KVM implementation can use it as well.
No functional change.
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
---
arch/s390/kvm/gmap/Makefile | 2 +-
arch/s390/kvm/gmap/kvm_mmu.c | 133 +++++++++++++++++++++++++++++++++++
arch/s390/kvm/gmap/kvm_mmu.h | 18 +++++
arch/s390/kvm/s390/s390.c | 126 ++++-----------------------------
arch/s390/kvm/s390/s390.h | 8 +++
5 files changed, 175 insertions(+), 112 deletions(-)
create mode 100644 arch/s390/kvm/gmap/kvm_mmu.c
create mode 100644 arch/s390/kvm/gmap/kvm_mmu.h
diff --git a/arch/s390/kvm/gmap/Makefile b/arch/s390/kvm/gmap/Makefile
index 3a4f8df11622..dd4ef062c536 100644
--- a/arch/s390/kvm/gmap/Makefile
+++ b/arch/s390/kvm/gmap/Makefile
@@ -2,4 +2,4 @@
GMAP ?= ../gmap
-gmap-y += $(GMAP)/dat.o $(GMAP)/gmap.o $(GMAP)/faultin.o
+gmap-y += $(GMAP)/dat.o $(GMAP)/gmap.o $(GMAP)/faultin.o $(GMAP)/kvm_mmu.o
diff --git a/arch/s390/kvm/gmap/kvm_mmu.c b/arch/s390/kvm/gmap/kvm_mmu.c
new file mode 100644
index 000000000000..b08b8229bb6f
--- /dev/null
+++ b/arch/s390/kvm/gmap/kvm_mmu.c
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/kvm_types.h>
+#include <linux/kvm_host.h>
+
+#include "s390.h"
+#include "gmap.h"
+#include "dat.h"
+#include "kvm_mmu.h"
+
+/*
+ * Get (and clear) the dirty memory log for a memory slot.
+ */
+int s390_kvm_mmu_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
+{
+ int r;
+ unsigned long n;
+ struct kvm_memory_slot *memslot;
+ int is_dirty;
+
+ if (kvm_is_ucontrol(kvm))
+ return -EINVAL;
+
+ mutex_lock(&kvm->slots_lock);
+
+ r = -EINVAL;
+ if (log->slot >= KVM_USER_MEM_SLOTS)
+ goto out;
+
+ r = kvm_get_dirty_log(kvm, log, &is_dirty, &memslot);
+ if (r)
+ goto out;
+
+ /* Clear the dirty log */
+ if (is_dirty) {
+ n = kvm_dirty_bitmap_bytes(memslot);
+ memset(memslot->dirty_bitmap, 0, n);
+ }
+ r = 0;
+out:
+ mutex_unlock(&kvm->slots_lock);
+ return r;
+}
+
+int s390_kvm_mmu_prepare_memory_region(struct kvm *kvm,
+ const struct kvm_memory_slot *old,
+ struct kvm_memory_slot *new,
+ enum kvm_mr_change change)
+{
+ if (kvm_is_ucontrol(kvm) && new && new->id < KVM_USER_MEM_SLOTS)
+ return -EINVAL;
+
+ /* When we are protected, we should not change the memory slots */
+ if (kvm_s390_pv_get_handle(kvm))
+ return -EINVAL;
+
+ if (change != KVM_MR_DELETE && change != KVM_MR_FLAGS_ONLY) {
+ /*
+ * A few sanity checks. The memory in userland is ok to be
+ * fragmented into various different vmas. It is okay to mmap()
+ * and munmap() stuff in this slot after doing this call at any
+ * time.
+ */
+ if (new->userspace_addr & ~PAGE_MASK)
+ return -EINVAL;
+ if ((new->base_gfn + new->npages) * PAGE_SIZE > kvm->arch.mem_limit)
+ return -EINVAL;
+ if (!asce_contains_gfn(kvm->arch.gmap->asce, new->base_gfn + new->npages - 1))
+ return -EINVAL;
+ }
+
+ if (!kvm_s390_is_migration_mode(kvm))
+ return 0;
+
+ /*
+ * Turn off migration mode when:
+ * - userspace creates a new memslot with dirty logging off,
+ * - userspace modifies an existing memslot (MOVE or FLAGS_ONLY) and
+ * dirty logging is turned off.
+ * Migration mode expects dirty page logging being enabled to store
+ * its dirty bitmap.
+ */
+ if (change != KVM_MR_DELETE &&
+ !(new->flags & KVM_MEM_LOG_DIRTY_PAGES))
+ WARN(kvm_s390_vm_stop_migration(kvm),
+ "Failed to stop migration mode");
+
+ return 0;
+}
+
+void s390_kvm_mmu_commit_memory_region(struct kvm *kvm,
+ struct kvm_memory_slot *old,
+ const struct kvm_memory_slot *new,
+ enum kvm_mr_change change)
+{
+ struct kvm_s390_mmu_cache *mc __free(kvm_s390_mmu_cache) = NULL;
+ int rc = 0;
+
+ guard(mutex)(&kvm->slots_arch_lock);
+
+ if (change == KVM_MR_FLAGS_ONLY)
+ return;
+
+ mc = kvm_s390_new_mmu_cache();
+ if (!mc) {
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ scoped_guard(write_lock, &kvm->mmu_lock) {
+ kvm_s390_update_cmma_dirty(kvm, old);
+ switch (change) {
+ case KVM_MR_DELETE:
+ rc = dat_delete_slot(mc, kvm->arch.gmap->asce, old->base_gfn, old->npages);
+ break;
+ case KVM_MR_MOVE:
+ rc = dat_delete_slot(mc, kvm->arch.gmap->asce, old->base_gfn, old->npages);
+ if (rc)
+ break;
+ fallthrough;
+ case KVM_MR_CREATE:
+ rc = dat_create_slot(mc, kvm->arch.gmap->asce, new->base_gfn, new->npages);
+ break;
+ case KVM_MR_FLAGS_ONLY:
+ break;
+ default:
+ WARN(1, "Unknown KVM MR CHANGE: %d\n", change);
+ }
+ }
+out:
+ if (rc)
+ pr_warn("failed to commit memory region\n");
+}
diff --git a/arch/s390/kvm/gmap/kvm_mmu.h b/arch/s390/kvm/gmap/kvm_mmu.h
new file mode 100644
index 000000000000..cdbd390bd33c
--- /dev/null
+++ b/arch/s390/kvm/gmap/kvm_mmu.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef ARCH_KVM_GMAP_KVM_MMU_H
+#define ARCH_KVM_GMAP_KVM_MMU_H
+
+#include <linux/kvm_host.h>
+
+int s390_kvm_mmu_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log);
+int s390_kvm_mmu_prepare_memory_region(struct kvm *kvm,
+ const struct kvm_memory_slot *old,
+ struct kvm_memory_slot *new,
+ enum kvm_mr_change change);
+void s390_kvm_mmu_commit_memory_region(struct kvm *kvm,
+ struct kvm_memory_slot *old,
+ const struct kvm_memory_slot *new,
+ enum kvm_mr_change change);
+
+#endif /* ARCH_KVM_GMAP_KVM_MMU_H */
diff --git a/arch/s390/kvm/s390/s390.c b/arch/s390/kvm/s390/s390.c
index ff09ffc10f0d..1d0d94f000f7 100644
--- a/arch/s390/kvm/s390/s390.c
+++ b/arch/s390/kvm/s390/s390.c
@@ -55,6 +55,7 @@
#include "gmap.h"
#include "faultin.h"
#include "pci.h"
+#include "kvm_mmu.h"
#define CREATE_TRACE_POINTS
#include "trace.h"
@@ -745,33 +746,7 @@ static void sca_del_vcpu(struct kvm_vcpu *vcpu);
int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
struct kvm_dirty_log *log)
{
- int r;
- unsigned long n;
- struct kvm_memory_slot *memslot;
- int is_dirty;
-
- if (kvm_is_ucontrol(kvm))
- return -EINVAL;
-
- mutex_lock(&kvm->slots_lock);
-
- r = -EINVAL;
- if (log->slot >= KVM_USER_MEM_SLOTS)
- goto out;
-
- r = kvm_get_dirty_log(kvm, log, &is_dirty, &memslot);
- if (r)
- goto out;
-
- /* Clear the dirty log */
- if (is_dirty) {
- n = kvm_dirty_bitmap_bytes(memslot);
- memset(memslot->dirty_bitmap, 0, n);
- }
- r = 0;
-out:
- mutex_unlock(&kvm->slots_lock);
- return r;
+ return s390_kvm_mmu_get_dirty_log(kvm, log);
}
static void icpt_operexc_on_all_vcpus(struct kvm *kvm)
@@ -1266,7 +1241,7 @@ static int kvm_s390_vm_start_migration(struct kvm *kvm)
* Must be called with kvm->slots_arch_lock to avoid races with ourselves,
* kvm_s390_vm_start_migration() and kvm_s390_get_cmma_bits().
*/
-static int kvm_s390_vm_stop_migration(struct kvm *kvm)
+int kvm_s390_vm_stop_migration(struct kvm *kvm)
{
/* migration mode already disabled */
if (!kvm->arch.migration_mode)
@@ -5770,45 +5745,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
struct kvm_memory_slot *new,
enum kvm_mr_change change)
{
- if (kvm_is_ucontrol(kvm) && new && new->id < KVM_USER_MEM_SLOTS)
- return -EINVAL;
-
- /* When we are protected, we should not change the memory slots */
- if (kvm_s390_pv_get_handle(kvm))
- return -EINVAL;
-
- if (change != KVM_MR_DELETE && change != KVM_MR_FLAGS_ONLY) {
- /*
- * A few sanity checks. The memory in userland is ok to be
- * fragmented into various different vmas. It is okay to mmap()
- * and munmap() stuff in this slot after doing this call at any
- * time.
- */
- if (new->userspace_addr & ~PAGE_MASK)
- return -EINVAL;
- if ((new->base_gfn + new->npages) * PAGE_SIZE > kvm->arch.mem_limit)
- return -EINVAL;
- if (!asce_contains_gfn(kvm->arch.gmap->asce, new->base_gfn + new->npages - 1))
- return -EINVAL;
- }
-
- if (!kvm->arch.migration_mode)
- return 0;
-
- /*
- * Turn off migration mode when:
- * - userspace creates a new memslot with dirty logging off,
- * - userspace modifies an existing memslot (MOVE or FLAGS_ONLY) and
- * dirty logging is turned off.
- * Migration mode expects dirty page logging being enabled to store
- * its dirty bitmap.
- */
- if (change != KVM_MR_DELETE &&
- !(new->flags & KVM_MEM_LOG_DIRTY_PAGES))
- WARN(kvm_s390_vm_stop_migration(kvm),
- "Failed to stop migration mode");
-
- return 0;
+ return s390_kvm_mmu_prepare_memory_region(kvm, old, new, change);
}
static long cmma_d_count_pte(union pte *ptep, gfn_t gfn, gfn_t next, struct dat_walk *walk)
@@ -5824,55 +5761,22 @@ static long cmma_d_count_pte(union pte *ptep, gfn_t gfn, gfn_t next, struct dat_
return 0;
}
-void kvm_arch_commit_memory_region(struct kvm *kvm,
- struct kvm_memory_slot *old,
- const struct kvm_memory_slot *new,
- enum kvm_mr_change change)
+void kvm_s390_update_cmma_dirty(struct kvm *kvm, struct kvm_memory_slot *old)
{
const struct dat_walk_ops ops = { .pte_entry = cmma_d_count_pte, };
- struct kvm_s390_mmu_cache *mc __free(kvm_s390_mmu_cache) = NULL;
- int rc = 0;
- guard(mutex)(&kvm->slots_arch_lock);
-
- if (change == KVM_MR_FLAGS_ONLY)
- return;
-
- mc = kvm_s390_new_mmu_cache();
- if (!mc) {
- rc = -ENOMEM;
- goto out;
+ if (kvm->arch.migration_mode && kvm->arch.use_cmma && old) {
+ _dat_walk_gfn_range(old->base_gfn, old->base_gfn + old->npages,
+ kvm->arch.gmap->asce, &ops, DAT_WALK_IGN_HOLES,
+ &kvm->arch.cmma_dirty_pages);
}
+}
- scoped_guard(write_lock, &kvm->mmu_lock) {
- if (kvm->arch.migration_mode && kvm->arch.use_cmma && old) {
- _dat_walk_gfn_range(old->base_gfn, old->base_gfn + old->npages,
- kvm->arch.gmap->asce, &ops, DAT_WALK_IGN_HOLES,
- &kvm->arch.cmma_dirty_pages);
- }
-
- switch (change) {
- case KVM_MR_DELETE:
- rc = dat_delete_slot(mc, kvm->arch.gmap->asce, old->base_gfn, old->npages);
- break;
- case KVM_MR_MOVE:
- rc = dat_delete_slot(mc, kvm->arch.gmap->asce, old->base_gfn, old->npages);
- if (rc)
- break;
- fallthrough;
- case KVM_MR_CREATE:
- rc = dat_create_slot(mc, kvm->arch.gmap->asce, new->base_gfn, new->npages);
- break;
- case KVM_MR_FLAGS_ONLY:
- break;
- default:
- WARN(1, "Unknown KVM MR CHANGE: %d\n", change);
- }
- }
-out:
- if (rc)
- pr_warn("failed to commit memory region\n");
- return;
+void kvm_arch_commit_memory_region(struct kvm *kvm, struct kvm_memory_slot *old,
+ const struct kvm_memory_slot *new,
+ enum kvm_mr_change change)
+{
+ s390_kvm_mmu_commit_memory_region(kvm, old, new, change);
}
/**
diff --git a/arch/s390/kvm/s390/s390.h b/arch/s390/kvm/s390/s390.h
index e144ca2e6d5e..d284a263ba70 100644
--- a/arch/s390/kvm/s390/s390.h
+++ b/arch/s390/kvm/s390/s390.h
@@ -472,6 +472,9 @@ int __kvm_s390_mprotect_many(struct gmap *gmap, gpa_t gpa, u8 npages, unsigned i
unsigned long bits);
bool kvm_arch_setup_async_pf(struct kvm_vcpu *vcpu);
+void kvm_s390_update_cmma_dirty(struct kvm *kvm, struct kvm_memory_slot *old);
+int kvm_s390_vm_stop_migration(struct kvm *kvm);
+
/* implemented in diag.c */
int kvm_s390_handle_diag(struct kvm_vcpu *vcpu);
@@ -594,6 +597,11 @@ static inline bool kvm_s390_cur_gmap_fault_is_write(void)
return test_facility(75) && (current->thread.gmap_teid.fsi == TEID_FSI_STORE);
}
+static __always_inline int kvm_s390_is_migration_mode(struct kvm *kvm)
+{
+ return kvm->arch.migration_mode;
+}
+
/**
* kvm_s390_vcpu_crypto_reset_all
*
--
2.53.0
next prev parent reply other threads:[~2026-08-12 15:37 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-12 15:35 [PATCH v6 00/33] KVM: s390: Introduce arm64 KVM Steffen Eiden
2026-08-12 15:35 ` [PATCH v6 01/33] vfio: Use file-based reference counting for KVM Steffen Eiden
2026-08-12 15:35 ` [PATCH v6 02/33] KVM: Make device name configurable Steffen Eiden
2026-08-12 15:35 ` [PATCH v6 03/33] KVM: Allow KVM implementations to switch off MMIO independent of Kconfig Steffen Eiden
2026-08-12 15:36 ` [PATCH v6 04/33] arm64: Use proper include variant Steffen Eiden
2026-08-12 15:36 ` [PATCH v6 05/33] arm64: ptrace: Use constants for compat register numbers Steffen Eiden
2026-08-12 15:36 ` [PATCH v6 06/33] arm64: sysreg: Convert SPSR_ELx to automatic register generation Steffen Eiden
2026-08-12 15:36 ` [PATCH v6 07/33] KVM: arm64: Access elements of vcpu_gp_regs individually Steffen Eiden
2026-08-12 15:36 ` [PATCH v6 08/33] KVM: arm64: Use accessor functions for core regs Steffen Eiden
2026-08-12 15:36 ` [PATCH v6 09/33] arm64: Prepare sharing arm64 headers with s390 Steffen Eiden
2026-08-12 15:36 ` [PATCH v6 10/33] arm64: Share " Steffen Eiden
2026-08-12 15:36 ` [PATCH v6 11/33] KVM: arm64: Share arm64 code " Steffen Eiden
2026-08-12 15:36 ` [PATCH v6 12/33] KVM: s390: Extract gmap tracing to a separate header Steffen Eiden
2026-08-12 17:13 ` Christian Borntraeger
2026-08-12 15:36 ` [PATCH v6 13/33] KVM: s390: Prepare include guards for a new location Steffen Eiden
2026-08-12 17:35 ` Christian Borntraeger
2026-08-12 15:36 ` [PATCH v6 14/33] KVM: s390: Rename kvm-s390.{c,h} to s390.{c,h} Steffen Eiden
2026-08-12 17:58 ` Christian Borntraeger
2026-08-12 15:36 ` [PATCH v6 15/33] KVM: s390: Move kvm_host definitions to kvm_host_s390 Steffen Eiden
2026-08-12 18:12 ` Christian Borntraeger
2026-08-12 15:36 ` [PATCH v6 16/33] KVM: s390: Move s390 kvm code into a subdirectory Steffen Eiden
2026-08-12 18:32 ` Christian Borntraeger
2026-08-12 15:36 ` [PATCH v6 17/33] KVM: s390: Move PGM code definitions to asm/kvm_host.h Steffen Eiden
2026-08-12 18:47 ` Christian Borntraeger
2026-08-12 15:36 ` Steffen Eiden [this message]
2026-08-12 19:05 ` [PATCH v6 18/33] KVM: s390: Prepare gmap for a second KVM implementation Christian Borntraeger
2026-08-12 15:36 ` [PATCH v6 19/33] KVM: s390: gmap: Make storage keys optional Steffen Eiden
2026-08-12 19:07 ` Christian Borntraeger
2026-08-12 15:36 ` [PATCH v6 20/33] KVM: s390: gmap: Make CMMA optional Steffen Eiden
2026-08-12 19:07 ` Christian Borntraeger
2026-08-12 15:36 ` [PATCH v6 21/33] KVM: s390: gmap: Make prefix handling optional Steffen Eiden
2026-08-12 19:10 ` Christian Borntraeger
2026-08-12 15:36 ` [PATCH v6 22/33] KVM: s390: Prepare KVM/s390 for a second KVM module Steffen Eiden
2026-08-12 15:36 ` [PATCH v6 23/33] s390: Use arm64 headers Steffen Eiden
2026-08-12 15:36 ` [PATCH v6 24/33] KVM: s390: Use arm64 code Steffen Eiden
2026-08-12 15:36 ` [PATCH v6 25/33] s390: Introduce Start Arm Execution instruction Steffen Eiden
2026-08-12 15:36 ` [PATCH v6 26/33] KVM: s390: arm64: Introduce host definitions Steffen Eiden
2026-08-12 15:36 ` [PATCH v6 27/33] s390/hwcaps: Report SAE support as hwcap Steffen Eiden
2026-08-12 15:36 ` [PATCH v6 28/33] KVM: s390: Add basic arm64 kvm module Steffen Eiden
2026-08-12 15:36 ` [PATCH v6 29/33] KVM: s390: arm64: Implement required functions Steffen Eiden
2026-08-12 15:36 ` [PATCH v6 30/33] KVM: s390: arm64: Implement vm/vcpu create destroy Steffen Eiden
2026-08-12 15:36 ` [PATCH v6 31/33] KVM: s390: arm64: Implement vCPU IOCTLs Steffen Eiden
2026-08-12 15:36 ` [PATCH v6 32/33] KVM: s390: arm64: Implement basic page fault handler Steffen Eiden
2026-08-12 15:36 ` [PATCH v6 33/33] KVM: s390: arm64: Enable KVM_ARM64 config and Kbuild Steffen Eiden
2026-08-12 16:28 ` [PATCH v6 00/33] KVM: s390: Introduce arm64 KVM Christian Borntraeger
2026-08-12 16:36 ` Sean Christopherson
2026-08-12 18:58 ` Steffen Eiden
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=20260812153631.3376090-19-seiden@linux.ibm.com \
--to=seiden@linux.ibm.com \
--cc=Ulrich.Weigand@de.ibm.com \
--cc=agordeev@linux.ibm.com \
--cc=arnd@arndb.de \
--cc=borntraeger@linux.ibm.com \
--cc=brueckner@linux.ibm.com \
--cc=catalin.marinas@arm.com \
--cc=david@kernel.org \
--cc=frankja@linux.ibm.com \
--cc=fritz@linux.ibm.com \
--cc=ggala@linux.ibm.com \
--cc=gor@linux.ibm.com \
--cc=gra@linux.ibm.com \
--cc=hari55@linux.ibm.com \
--cc=hca@linux.ibm.com \
--cc=iii@linux.ibm.com \
--cc=imbrenda@linux.ibm.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-kernel@vger.kernel.org \
--cc=linux-s390@vger.kernel.org \
--cc=maz@kernel.org \
--cc=nrb@linux.ibm.com \
--cc=oss@nina.schoetterlglausch.eu \
--cc=oupton@kernel.org \
--cc=pbonzini@redhat.com \
--cc=seanjc@google.com \
--cc=suzuki.poulose@arm.com \
--cc=svens@linux.ibm.com \
--cc=tabba@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