All of lore.kernel.org
 help / color / mirror / Atom feed
From: Will Deacon <will@kernel.org>
To: kvmarm@lists.cs.columbia.edu
Cc: Marc Zyngier <maz@kernel.org>,
	kernel-team@android.com, kvm@vger.kernel.org,
	Andy Lutomirski <luto@amacapital.net>,
	linux-arm-kernel@lists.infradead.org,
	Michael Roth <michael.roth@amd.com>,
	Catalin Marinas <catalin.marinas@arm.com>,
	Chao Peng <chao.p.peng@linux.intel.com>,
	Will Deacon <will@kernel.org>
Subject: [PATCH 67/89] KVM: arm64: Add EL2 entry/exit handlers for pKVM guests
Date: Thu, 19 May 2022 14:41:42 +0100	[thread overview]
Message-ID: <20220519134204.5379-68-will@kernel.org> (raw)
In-Reply-To: <20220519134204.5379-1-will@kernel.org>

From: Fuad Tabba <tabba@google.com>

Introduce separate El2 entry/exit handlers for protected and
non-protected guests under pKVM and hook up the protected handlers to
expose the minimum amount of data to the host required for EL1 handling.

Signed-off-by: Fuad Tabba <tabba@google.com>
---
 arch/arm64/kvm/hyp/nvhe/hyp-main.c | 230 ++++++++++++++++++++++++++++-
 1 file changed, 228 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index e987f34641dd..692576497ed9 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -20,6 +20,8 @@
 
 #include <linux/irqchip/arm-gic-v3.h>
 
+#include "../../sys_regs.h"
+
 /*
  * Host FPSIMD state. Written to when the guest accesses its own FPSIMD state,
  * and read when the guest state is live and we need to switch back to the host.
@@ -34,6 +36,207 @@ void __kvm_hyp_host_forward_smc(struct kvm_cpu_context *host_ctxt);
 
 typedef void (*shadow_entry_exit_handler_fn)(struct kvm_vcpu *, struct kvm_vcpu *);
 
+static void handle_pvm_entry_wfx(struct kvm_vcpu *host_vcpu, struct kvm_vcpu *shadow_vcpu)
+{
+	shadow_vcpu->arch.flags |= READ_ONCE(host_vcpu->arch.flags) &
+				   KVM_ARM64_INCREMENT_PC;
+}
+
+static void handle_pvm_entry_sys64(struct kvm_vcpu *host_vcpu, struct kvm_vcpu *shadow_vcpu)
+{
+	unsigned long host_flags;
+
+	host_flags = READ_ONCE(host_vcpu->arch.flags);
+
+	/* Exceptions have priority on anything else */
+	if (host_flags & KVM_ARM64_PENDING_EXCEPTION) {
+		/* Exceptions caused by this should be undef exceptions. */
+		u32 esr = (ESR_ELx_EC_UNKNOWN << ESR_ELx_EC_SHIFT);
+
+		__vcpu_sys_reg(shadow_vcpu, ESR_EL1) = esr;
+		shadow_vcpu->arch.flags &= ~(KVM_ARM64_PENDING_EXCEPTION |
+					     KVM_ARM64_EXCEPT_MASK);
+		shadow_vcpu->arch.flags |= (KVM_ARM64_PENDING_EXCEPTION |
+					    KVM_ARM64_EXCEPT_AA64_ELx_SYNC |
+					    KVM_ARM64_EXCEPT_AA64_EL1);
+
+		return;
+	}
+
+	if (host_flags & KVM_ARM64_INCREMENT_PC) {
+		shadow_vcpu->arch.flags &= ~(KVM_ARM64_PENDING_EXCEPTION |
+					     KVM_ARM64_EXCEPT_MASK);
+		shadow_vcpu->arch.flags |= KVM_ARM64_INCREMENT_PC;
+	}
+
+	if (!esr_sys64_to_params(shadow_vcpu->arch.fault.esr_el2).is_write) {
+		/* r0 as transfer register between the guest and the host. */
+		u64 rt_val = READ_ONCE(host_vcpu->arch.ctxt.regs.regs[0]);
+		int rt = kvm_vcpu_sys_get_rt(shadow_vcpu);
+
+		vcpu_set_reg(shadow_vcpu, rt, rt_val);
+	}
+}
+
+static void handle_pvm_entry_iabt(struct kvm_vcpu *host_vcpu, struct kvm_vcpu *shadow_vcpu)
+{
+	unsigned long cpsr = *vcpu_cpsr(shadow_vcpu);
+	unsigned long host_flags;
+	u32 esr = ESR_ELx_IL;
+
+	host_flags = READ_ONCE(host_vcpu->arch.flags);
+
+	if (!(host_flags & KVM_ARM64_PENDING_EXCEPTION))
+		return;
+
+	/*
+	 * If the host wants to inject an exception, get syndrom and
+	 * fault address.
+	 */
+	if ((cpsr & PSR_MODE_MASK) == PSR_MODE_EL0t)
+		esr |= (ESR_ELx_EC_IABT_LOW << ESR_ELx_EC_SHIFT);
+	else
+		esr |= (ESR_ELx_EC_IABT_CUR << ESR_ELx_EC_SHIFT);
+
+	esr |= ESR_ELx_FSC_EXTABT;
+
+	__vcpu_sys_reg(shadow_vcpu, ESR_EL1) = esr;
+	__vcpu_sys_reg(shadow_vcpu, FAR_EL1) = kvm_vcpu_get_hfar(shadow_vcpu);
+
+	/* Tell the run loop that we want to inject something */
+	shadow_vcpu->arch.flags &= ~(KVM_ARM64_PENDING_EXCEPTION |
+				     KVM_ARM64_EXCEPT_MASK);
+	shadow_vcpu->arch.flags |= (KVM_ARM64_PENDING_EXCEPTION |
+				    KVM_ARM64_EXCEPT_AA64_ELx_SYNC |
+				    KVM_ARM64_EXCEPT_AA64_EL1);
+}
+
+static void handle_pvm_entry_dabt(struct kvm_vcpu *host_vcpu, struct kvm_vcpu *shadow_vcpu)
+{
+	unsigned long host_flags;
+	bool rd_update;
+
+	host_flags = READ_ONCE(host_vcpu->arch.flags);
+
+	/* Exceptions have priority over anything else */
+	if (host_flags & KVM_ARM64_PENDING_EXCEPTION) {
+		unsigned long cpsr = *vcpu_cpsr(shadow_vcpu);
+		u32 esr = ESR_ELx_IL;
+
+		if ((cpsr & PSR_MODE_MASK) == PSR_MODE_EL0t)
+			esr |= (ESR_ELx_EC_DABT_LOW << ESR_ELx_EC_SHIFT);
+		else
+			esr |= (ESR_ELx_EC_DABT_CUR << ESR_ELx_EC_SHIFT);
+
+		esr |= ESR_ELx_FSC_EXTABT;
+
+		__vcpu_sys_reg(shadow_vcpu, ESR_EL1) = esr;
+		__vcpu_sys_reg(shadow_vcpu, FAR_EL1) = kvm_vcpu_get_hfar(shadow_vcpu);
+		/* Tell the run loop that we want to inject something */
+		shadow_vcpu->arch.flags &= ~(KVM_ARM64_PENDING_EXCEPTION |
+					     KVM_ARM64_EXCEPT_MASK);
+		shadow_vcpu->arch.flags |= (KVM_ARM64_PENDING_EXCEPTION |
+					    KVM_ARM64_EXCEPT_AA64_ELx_SYNC |
+					    KVM_ARM64_EXCEPT_AA64_EL1);
+
+		/* Cancel potential in-flight MMIO */
+		shadow_vcpu->mmio_needed = false;
+		return;
+	}
+
+	/* Handle PC increment on MMIO */
+	if ((host_flags & KVM_ARM64_INCREMENT_PC) && shadow_vcpu->mmio_needed) {
+		shadow_vcpu->arch.flags &= ~(KVM_ARM64_PENDING_EXCEPTION |
+					     KVM_ARM64_EXCEPT_MASK);
+		shadow_vcpu->arch.flags |= KVM_ARM64_INCREMENT_PC;
+	}
+
+	/* If we were doing an MMIO read access, update the register*/
+	rd_update = (shadow_vcpu->mmio_needed &&
+		     (host_flags & KVM_ARM64_INCREMENT_PC));
+	rd_update &= !kvm_vcpu_dabt_iswrite(shadow_vcpu);
+
+	if (rd_update) {
+		/* r0 as transfer register between the guest and the host. */
+		u64 rd_val = READ_ONCE(host_vcpu->arch.ctxt.regs.regs[0]);
+		int rd = kvm_vcpu_dabt_get_rd(shadow_vcpu);
+
+		vcpu_set_reg(shadow_vcpu, rd, rd_val);
+	}
+
+	shadow_vcpu->mmio_needed = false;
+}
+
+static void handle_pvm_exit_wfx(struct kvm_vcpu *host_vcpu, struct kvm_vcpu *shadow_vcpu)
+{
+	WRITE_ONCE(host_vcpu->arch.ctxt.regs.pstate,
+		   shadow_vcpu->arch.ctxt.regs.pstate & PSR_MODE_MASK);
+	WRITE_ONCE(host_vcpu->arch.fault.esr_el2,
+		   shadow_vcpu->arch.fault.esr_el2);
+}
+
+static void handle_pvm_exit_sys64(struct kvm_vcpu *host_vcpu, struct kvm_vcpu *shadow_vcpu)
+{
+	u32 esr_el2 = shadow_vcpu->arch.fault.esr_el2;
+
+	/* r0 as transfer register between the guest and the host. */
+	WRITE_ONCE(host_vcpu->arch.fault.esr_el2,
+		   esr_el2 & ~ESR_ELx_SYS64_ISS_RT_MASK);
+
+	/* The mode is required for the host to emulate some sysregs */
+	WRITE_ONCE(host_vcpu->arch.ctxt.regs.pstate,
+		   shadow_vcpu->arch.ctxt.regs.pstate & PSR_MODE_MASK);
+
+	if (esr_sys64_to_params(esr_el2).is_write) {
+		int rt = kvm_vcpu_sys_get_rt(shadow_vcpu);
+		u64 rt_val = vcpu_get_reg(shadow_vcpu, rt);
+
+		WRITE_ONCE(host_vcpu->arch.ctxt.regs.regs[0], rt_val);
+	}
+}
+
+static void handle_pvm_exit_iabt(struct kvm_vcpu *host_vcpu, struct kvm_vcpu *shadow_vcpu)
+{
+	WRITE_ONCE(host_vcpu->arch.fault.esr_el2,
+		   shadow_vcpu->arch.fault.esr_el2);
+	WRITE_ONCE(host_vcpu->arch.fault.hpfar_el2,
+		   shadow_vcpu->arch.fault.hpfar_el2);
+}
+
+static void handle_pvm_exit_dabt(struct kvm_vcpu *host_vcpu, struct kvm_vcpu *shadow_vcpu)
+{
+	/*
+	 * For now, we treat all data aborts as MMIO since we have no knowledge
+	 * of the memslot configuration at EL2.
+	 */
+	shadow_vcpu->mmio_needed = true;
+
+	if (shadow_vcpu->mmio_needed) {
+		/* r0 as transfer register between the guest and the host. */
+		WRITE_ONCE(host_vcpu->arch.fault.esr_el2,
+			   shadow_vcpu->arch.fault.esr_el2 & ~ESR_ELx_SRT_MASK);
+
+		if (kvm_vcpu_dabt_iswrite(shadow_vcpu)) {
+			int rt = kvm_vcpu_dabt_get_rd(shadow_vcpu);
+			u64 rt_val = vcpu_get_reg(shadow_vcpu, rt);
+
+			WRITE_ONCE(host_vcpu->arch.ctxt.regs.regs[0], rt_val);
+		}
+	} else {
+		WRITE_ONCE(host_vcpu->arch.fault.esr_el2,
+			   shadow_vcpu->arch.fault.esr_el2 & ~ESR_ELx_ISV);
+	}
+
+	WRITE_ONCE(host_vcpu->arch.ctxt.regs.pstate,
+		   shadow_vcpu->arch.ctxt.regs.pstate & PSR_MODE_MASK);
+	WRITE_ONCE(host_vcpu->arch.fault.far_el2,
+		   shadow_vcpu->arch.fault.far_el2 & GENMASK(11, 0));
+	WRITE_ONCE(host_vcpu->arch.fault.hpfar_el2,
+		   shadow_vcpu->arch.fault.hpfar_el2);
+	WRITE_ONCE(__vcpu_sys_reg(host_vcpu, SCTLR_EL1),
+		   __vcpu_sys_reg(shadow_vcpu, SCTLR_EL1) & (SCTLR_ELx_EE | SCTLR_EL1_E0E));
+}
+
 static void handle_vm_entry_generic(struct kvm_vcpu *host_vcpu, struct kvm_vcpu *shadow_vcpu)
 {
 	unsigned long host_flags = READ_ONCE(host_vcpu->arch.flags);
@@ -67,6 +270,22 @@ static void handle_vm_exit_abt(struct kvm_vcpu *host_vcpu, struct kvm_vcpu *shad
 		   shadow_vcpu->arch.fault.disr_el1);
 }
 
+static const shadow_entry_exit_handler_fn entry_pvm_shadow_handlers[] = {
+	[0 ... ESR_ELx_EC_MAX]		= NULL,
+	[ESR_ELx_EC_WFx]		= handle_pvm_entry_wfx,
+	[ESR_ELx_EC_SYS64]		= handle_pvm_entry_sys64,
+	[ESR_ELx_EC_IABT_LOW]		= handle_pvm_entry_iabt,
+	[ESR_ELx_EC_DABT_LOW]		= handle_pvm_entry_dabt,
+};
+
+static const shadow_entry_exit_handler_fn exit_pvm_shadow_handlers[] = {
+	[0 ... ESR_ELx_EC_MAX]		= NULL,
+	[ESR_ELx_EC_WFx]		= handle_pvm_exit_wfx,
+	[ESR_ELx_EC_SYS64]		= handle_pvm_exit_sys64,
+	[ESR_ELx_EC_IABT_LOW]		= handle_pvm_exit_iabt,
+	[ESR_ELx_EC_DABT_LOW]		= handle_pvm_exit_dabt,
+};
+
 static const shadow_entry_exit_handler_fn entry_vm_shadow_handlers[] = {
 	[0 ... ESR_ELx_EC_MAX]		= handle_vm_entry_generic,
 };
@@ -219,9 +438,13 @@ static void flush_shadow_state(struct kvm_shadow_vcpu_state *shadow_state)
 		break;
 	case ARM_EXCEPTION_TRAP:
 		esr_ec = ESR_ELx_EC(kvm_vcpu_get_esr(shadow_vcpu));
-		ec_handler = entry_vm_shadow_handlers[esr_ec];
+		if (shadow_state_is_protected(shadow_state))
+			ec_handler = entry_pvm_shadow_handlers[esr_ec];
+		else
+			ec_handler = entry_vm_shadow_handlers[esr_ec];
 		if (ec_handler)
 			ec_handler(host_vcpu, shadow_vcpu);
+
 		break;
 	default:
 		BUG();
@@ -251,7 +474,10 @@ static void sync_shadow_state(struct kvm_shadow_vcpu_state *shadow_state,
 		break;
 	case ARM_EXCEPTION_TRAP:
 		esr_ec = ESR_ELx_EC(kvm_vcpu_get_esr(shadow_vcpu));
-		ec_handler = exit_vm_shadow_handlers[esr_ec];
+		if (shadow_state_is_protected(shadow_state))
+			ec_handler = exit_pvm_shadow_handlers[esr_ec];
+		else
+			ec_handler = exit_vm_shadow_handlers[esr_ec];
 		if (ec_handler)
 			ec_handler(host_vcpu, shadow_vcpu);
 		break;
-- 
2.36.1.124.g0e6072fb45-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: Will Deacon <will@kernel.org>
To: kvmarm@lists.cs.columbia.edu
Cc: Will Deacon <will@kernel.org>, Ard Biesheuvel <ardb@kernel.org>,
	Sean Christopherson <seanjc@google.com>,
	Alexandru Elisei <alexandru.elisei@arm.com>,
	Andy Lutomirski <luto@amacapital.net>,
	Catalin Marinas <catalin.marinas@arm.com>,
	James Morse <james.morse@arm.com>,
	Chao Peng <chao.p.peng@linux.intel.com>,
	Quentin Perret <qperret@google.com>,
	Suzuki K Poulose <suzuki.poulose@arm.com>,
	Michael Roth <michael.roth@amd.com>,
	Mark Rutland <mark.rutland@arm.com>,
	Fuad Tabba <tabba@google.com>, Oliver Upton <oupton@google.com>,
	Marc Zyngier <maz@kernel.org>,
	kernel-team@android.com, kvm@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org
Subject: [PATCH 67/89] KVM: arm64: Add EL2 entry/exit handlers for pKVM guests
Date: Thu, 19 May 2022 14:41:42 +0100	[thread overview]
Message-ID: <20220519134204.5379-68-will@kernel.org> (raw)
In-Reply-To: <20220519134204.5379-1-will@kernel.org>

From: Fuad Tabba <tabba@google.com>

Introduce separate El2 entry/exit handlers for protected and
non-protected guests under pKVM and hook up the protected handlers to
expose the minimum amount of data to the host required for EL1 handling.

Signed-off-by: Fuad Tabba <tabba@google.com>
---
 arch/arm64/kvm/hyp/nvhe/hyp-main.c | 230 ++++++++++++++++++++++++++++-
 1 file changed, 228 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index e987f34641dd..692576497ed9 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -20,6 +20,8 @@
 
 #include <linux/irqchip/arm-gic-v3.h>
 
+#include "../../sys_regs.h"
+
 /*
  * Host FPSIMD state. Written to when the guest accesses its own FPSIMD state,
  * and read when the guest state is live and we need to switch back to the host.
@@ -34,6 +36,207 @@ void __kvm_hyp_host_forward_smc(struct kvm_cpu_context *host_ctxt);
 
 typedef void (*shadow_entry_exit_handler_fn)(struct kvm_vcpu *, struct kvm_vcpu *);
 
+static void handle_pvm_entry_wfx(struct kvm_vcpu *host_vcpu, struct kvm_vcpu *shadow_vcpu)
+{
+	shadow_vcpu->arch.flags |= READ_ONCE(host_vcpu->arch.flags) &
+				   KVM_ARM64_INCREMENT_PC;
+}
+
+static void handle_pvm_entry_sys64(struct kvm_vcpu *host_vcpu, struct kvm_vcpu *shadow_vcpu)
+{
+	unsigned long host_flags;
+
+	host_flags = READ_ONCE(host_vcpu->arch.flags);
+
+	/* Exceptions have priority on anything else */
+	if (host_flags & KVM_ARM64_PENDING_EXCEPTION) {
+		/* Exceptions caused by this should be undef exceptions. */
+		u32 esr = (ESR_ELx_EC_UNKNOWN << ESR_ELx_EC_SHIFT);
+
+		__vcpu_sys_reg(shadow_vcpu, ESR_EL1) = esr;
+		shadow_vcpu->arch.flags &= ~(KVM_ARM64_PENDING_EXCEPTION |
+					     KVM_ARM64_EXCEPT_MASK);
+		shadow_vcpu->arch.flags |= (KVM_ARM64_PENDING_EXCEPTION |
+					    KVM_ARM64_EXCEPT_AA64_ELx_SYNC |
+					    KVM_ARM64_EXCEPT_AA64_EL1);
+
+		return;
+	}
+
+	if (host_flags & KVM_ARM64_INCREMENT_PC) {
+		shadow_vcpu->arch.flags &= ~(KVM_ARM64_PENDING_EXCEPTION |
+					     KVM_ARM64_EXCEPT_MASK);
+		shadow_vcpu->arch.flags |= KVM_ARM64_INCREMENT_PC;
+	}
+
+	if (!esr_sys64_to_params(shadow_vcpu->arch.fault.esr_el2).is_write) {
+		/* r0 as transfer register between the guest and the host. */
+		u64 rt_val = READ_ONCE(host_vcpu->arch.ctxt.regs.regs[0]);
+		int rt = kvm_vcpu_sys_get_rt(shadow_vcpu);
+
+		vcpu_set_reg(shadow_vcpu, rt, rt_val);
+	}
+}
+
+static void handle_pvm_entry_iabt(struct kvm_vcpu *host_vcpu, struct kvm_vcpu *shadow_vcpu)
+{
+	unsigned long cpsr = *vcpu_cpsr(shadow_vcpu);
+	unsigned long host_flags;
+	u32 esr = ESR_ELx_IL;
+
+	host_flags = READ_ONCE(host_vcpu->arch.flags);
+
+	if (!(host_flags & KVM_ARM64_PENDING_EXCEPTION))
+		return;
+
+	/*
+	 * If the host wants to inject an exception, get syndrom and
+	 * fault address.
+	 */
+	if ((cpsr & PSR_MODE_MASK) == PSR_MODE_EL0t)
+		esr |= (ESR_ELx_EC_IABT_LOW << ESR_ELx_EC_SHIFT);
+	else
+		esr |= (ESR_ELx_EC_IABT_CUR << ESR_ELx_EC_SHIFT);
+
+	esr |= ESR_ELx_FSC_EXTABT;
+
+	__vcpu_sys_reg(shadow_vcpu, ESR_EL1) = esr;
+	__vcpu_sys_reg(shadow_vcpu, FAR_EL1) = kvm_vcpu_get_hfar(shadow_vcpu);
+
+	/* Tell the run loop that we want to inject something */
+	shadow_vcpu->arch.flags &= ~(KVM_ARM64_PENDING_EXCEPTION |
+				     KVM_ARM64_EXCEPT_MASK);
+	shadow_vcpu->arch.flags |= (KVM_ARM64_PENDING_EXCEPTION |
+				    KVM_ARM64_EXCEPT_AA64_ELx_SYNC |
+				    KVM_ARM64_EXCEPT_AA64_EL1);
+}
+
+static void handle_pvm_entry_dabt(struct kvm_vcpu *host_vcpu, struct kvm_vcpu *shadow_vcpu)
+{
+	unsigned long host_flags;
+	bool rd_update;
+
+	host_flags = READ_ONCE(host_vcpu->arch.flags);
+
+	/* Exceptions have priority over anything else */
+	if (host_flags & KVM_ARM64_PENDING_EXCEPTION) {
+		unsigned long cpsr = *vcpu_cpsr(shadow_vcpu);
+		u32 esr = ESR_ELx_IL;
+
+		if ((cpsr & PSR_MODE_MASK) == PSR_MODE_EL0t)
+			esr |= (ESR_ELx_EC_DABT_LOW << ESR_ELx_EC_SHIFT);
+		else
+			esr |= (ESR_ELx_EC_DABT_CUR << ESR_ELx_EC_SHIFT);
+
+		esr |= ESR_ELx_FSC_EXTABT;
+
+		__vcpu_sys_reg(shadow_vcpu, ESR_EL1) = esr;
+		__vcpu_sys_reg(shadow_vcpu, FAR_EL1) = kvm_vcpu_get_hfar(shadow_vcpu);
+		/* Tell the run loop that we want to inject something */
+		shadow_vcpu->arch.flags &= ~(KVM_ARM64_PENDING_EXCEPTION |
+					     KVM_ARM64_EXCEPT_MASK);
+		shadow_vcpu->arch.flags |= (KVM_ARM64_PENDING_EXCEPTION |
+					    KVM_ARM64_EXCEPT_AA64_ELx_SYNC |
+					    KVM_ARM64_EXCEPT_AA64_EL1);
+
+		/* Cancel potential in-flight MMIO */
+		shadow_vcpu->mmio_needed = false;
+		return;
+	}
+
+	/* Handle PC increment on MMIO */
+	if ((host_flags & KVM_ARM64_INCREMENT_PC) && shadow_vcpu->mmio_needed) {
+		shadow_vcpu->arch.flags &= ~(KVM_ARM64_PENDING_EXCEPTION |
+					     KVM_ARM64_EXCEPT_MASK);
+		shadow_vcpu->arch.flags |= KVM_ARM64_INCREMENT_PC;
+	}
+
+	/* If we were doing an MMIO read access, update the register*/
+	rd_update = (shadow_vcpu->mmio_needed &&
+		     (host_flags & KVM_ARM64_INCREMENT_PC));
+	rd_update &= !kvm_vcpu_dabt_iswrite(shadow_vcpu);
+
+	if (rd_update) {
+		/* r0 as transfer register between the guest and the host. */
+		u64 rd_val = READ_ONCE(host_vcpu->arch.ctxt.regs.regs[0]);
+		int rd = kvm_vcpu_dabt_get_rd(shadow_vcpu);
+
+		vcpu_set_reg(shadow_vcpu, rd, rd_val);
+	}
+
+	shadow_vcpu->mmio_needed = false;
+}
+
+static void handle_pvm_exit_wfx(struct kvm_vcpu *host_vcpu, struct kvm_vcpu *shadow_vcpu)
+{
+	WRITE_ONCE(host_vcpu->arch.ctxt.regs.pstate,
+		   shadow_vcpu->arch.ctxt.regs.pstate & PSR_MODE_MASK);
+	WRITE_ONCE(host_vcpu->arch.fault.esr_el2,
+		   shadow_vcpu->arch.fault.esr_el2);
+}
+
+static void handle_pvm_exit_sys64(struct kvm_vcpu *host_vcpu, struct kvm_vcpu *shadow_vcpu)
+{
+	u32 esr_el2 = shadow_vcpu->arch.fault.esr_el2;
+
+	/* r0 as transfer register between the guest and the host. */
+	WRITE_ONCE(host_vcpu->arch.fault.esr_el2,
+		   esr_el2 & ~ESR_ELx_SYS64_ISS_RT_MASK);
+
+	/* The mode is required for the host to emulate some sysregs */
+	WRITE_ONCE(host_vcpu->arch.ctxt.regs.pstate,
+		   shadow_vcpu->arch.ctxt.regs.pstate & PSR_MODE_MASK);
+
+	if (esr_sys64_to_params(esr_el2).is_write) {
+		int rt = kvm_vcpu_sys_get_rt(shadow_vcpu);
+		u64 rt_val = vcpu_get_reg(shadow_vcpu, rt);
+
+		WRITE_ONCE(host_vcpu->arch.ctxt.regs.regs[0], rt_val);
+	}
+}
+
+static void handle_pvm_exit_iabt(struct kvm_vcpu *host_vcpu, struct kvm_vcpu *shadow_vcpu)
+{
+	WRITE_ONCE(host_vcpu->arch.fault.esr_el2,
+		   shadow_vcpu->arch.fault.esr_el2);
+	WRITE_ONCE(host_vcpu->arch.fault.hpfar_el2,
+		   shadow_vcpu->arch.fault.hpfar_el2);
+}
+
+static void handle_pvm_exit_dabt(struct kvm_vcpu *host_vcpu, struct kvm_vcpu *shadow_vcpu)
+{
+	/*
+	 * For now, we treat all data aborts as MMIO since we have no knowledge
+	 * of the memslot configuration at EL2.
+	 */
+	shadow_vcpu->mmio_needed = true;
+
+	if (shadow_vcpu->mmio_needed) {
+		/* r0 as transfer register between the guest and the host. */
+		WRITE_ONCE(host_vcpu->arch.fault.esr_el2,
+			   shadow_vcpu->arch.fault.esr_el2 & ~ESR_ELx_SRT_MASK);
+
+		if (kvm_vcpu_dabt_iswrite(shadow_vcpu)) {
+			int rt = kvm_vcpu_dabt_get_rd(shadow_vcpu);
+			u64 rt_val = vcpu_get_reg(shadow_vcpu, rt);
+
+			WRITE_ONCE(host_vcpu->arch.ctxt.regs.regs[0], rt_val);
+		}
+	} else {
+		WRITE_ONCE(host_vcpu->arch.fault.esr_el2,
+			   shadow_vcpu->arch.fault.esr_el2 & ~ESR_ELx_ISV);
+	}
+
+	WRITE_ONCE(host_vcpu->arch.ctxt.regs.pstate,
+		   shadow_vcpu->arch.ctxt.regs.pstate & PSR_MODE_MASK);
+	WRITE_ONCE(host_vcpu->arch.fault.far_el2,
+		   shadow_vcpu->arch.fault.far_el2 & GENMASK(11, 0));
+	WRITE_ONCE(host_vcpu->arch.fault.hpfar_el2,
+		   shadow_vcpu->arch.fault.hpfar_el2);
+	WRITE_ONCE(__vcpu_sys_reg(host_vcpu, SCTLR_EL1),
+		   __vcpu_sys_reg(shadow_vcpu, SCTLR_EL1) & (SCTLR_ELx_EE | SCTLR_EL1_E0E));
+}
+
 static void handle_vm_entry_generic(struct kvm_vcpu *host_vcpu, struct kvm_vcpu *shadow_vcpu)
 {
 	unsigned long host_flags = READ_ONCE(host_vcpu->arch.flags);
@@ -67,6 +270,22 @@ static void handle_vm_exit_abt(struct kvm_vcpu *host_vcpu, struct kvm_vcpu *shad
 		   shadow_vcpu->arch.fault.disr_el1);
 }
 
+static const shadow_entry_exit_handler_fn entry_pvm_shadow_handlers[] = {
+	[0 ... ESR_ELx_EC_MAX]		= NULL,
+	[ESR_ELx_EC_WFx]		= handle_pvm_entry_wfx,
+	[ESR_ELx_EC_SYS64]		= handle_pvm_entry_sys64,
+	[ESR_ELx_EC_IABT_LOW]		= handle_pvm_entry_iabt,
+	[ESR_ELx_EC_DABT_LOW]		= handle_pvm_entry_dabt,
+};
+
+static const shadow_entry_exit_handler_fn exit_pvm_shadow_handlers[] = {
+	[0 ... ESR_ELx_EC_MAX]		= NULL,
+	[ESR_ELx_EC_WFx]		= handle_pvm_exit_wfx,
+	[ESR_ELx_EC_SYS64]		= handle_pvm_exit_sys64,
+	[ESR_ELx_EC_IABT_LOW]		= handle_pvm_exit_iabt,
+	[ESR_ELx_EC_DABT_LOW]		= handle_pvm_exit_dabt,
+};
+
 static const shadow_entry_exit_handler_fn entry_vm_shadow_handlers[] = {
 	[0 ... ESR_ELx_EC_MAX]		= handle_vm_entry_generic,
 };
@@ -219,9 +438,13 @@ static void flush_shadow_state(struct kvm_shadow_vcpu_state *shadow_state)
 		break;
 	case ARM_EXCEPTION_TRAP:
 		esr_ec = ESR_ELx_EC(kvm_vcpu_get_esr(shadow_vcpu));
-		ec_handler = entry_vm_shadow_handlers[esr_ec];
+		if (shadow_state_is_protected(shadow_state))
+			ec_handler = entry_pvm_shadow_handlers[esr_ec];
+		else
+			ec_handler = entry_vm_shadow_handlers[esr_ec];
 		if (ec_handler)
 			ec_handler(host_vcpu, shadow_vcpu);
+
 		break;
 	default:
 		BUG();
@@ -251,7 +474,10 @@ static void sync_shadow_state(struct kvm_shadow_vcpu_state *shadow_state,
 		break;
 	case ARM_EXCEPTION_TRAP:
 		esr_ec = ESR_ELx_EC(kvm_vcpu_get_esr(shadow_vcpu));
-		ec_handler = exit_vm_shadow_handlers[esr_ec];
+		if (shadow_state_is_protected(shadow_state))
+			ec_handler = exit_pvm_shadow_handlers[esr_ec];
+		else
+			ec_handler = exit_vm_shadow_handlers[esr_ec];
 		if (ec_handler)
 			ec_handler(host_vcpu, shadow_vcpu);
 		break;
-- 
2.36.1.124.g0e6072fb45-goog


WARNING: multiple messages have this Message-ID (diff)
From: Will Deacon <will@kernel.org>
To: kvmarm@lists.cs.columbia.edu
Cc: Will Deacon <will@kernel.org>, Ard Biesheuvel <ardb@kernel.org>,
	Sean Christopherson <seanjc@google.com>,
	Alexandru Elisei <alexandru.elisei@arm.com>,
	Andy Lutomirski <luto@amacapital.net>,
	Catalin Marinas <catalin.marinas@arm.com>,
	James Morse <james.morse@arm.com>,
	Chao Peng <chao.p.peng@linux.intel.com>,
	Quentin Perret <qperret@google.com>,
	Suzuki K Poulose <suzuki.poulose@arm.com>,
	Michael Roth <michael.roth@amd.com>,
	Mark Rutland <mark.rutland@arm.com>,
	Fuad Tabba <tabba@google.com>, Oliver Upton <oupton@google.com>,
	Marc Zyngier <maz@kernel.org>,
	kernel-team@android.com, kvm@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org
Subject: [PATCH 67/89] KVM: arm64: Add EL2 entry/exit handlers for pKVM guests
Date: Thu, 19 May 2022 14:41:42 +0100	[thread overview]
Message-ID: <20220519134204.5379-68-will@kernel.org> (raw)
In-Reply-To: <20220519134204.5379-1-will@kernel.org>

From: Fuad Tabba <tabba@google.com>

Introduce separate El2 entry/exit handlers for protected and
non-protected guests under pKVM and hook up the protected handlers to
expose the minimum amount of data to the host required for EL1 handling.

Signed-off-by: Fuad Tabba <tabba@google.com>
---
 arch/arm64/kvm/hyp/nvhe/hyp-main.c | 230 ++++++++++++++++++++++++++++-
 1 file changed, 228 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index e987f34641dd..692576497ed9 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -20,6 +20,8 @@
 
 #include <linux/irqchip/arm-gic-v3.h>
 
+#include "../../sys_regs.h"
+
 /*
  * Host FPSIMD state. Written to when the guest accesses its own FPSIMD state,
  * and read when the guest state is live and we need to switch back to the host.
@@ -34,6 +36,207 @@ void __kvm_hyp_host_forward_smc(struct kvm_cpu_context *host_ctxt);
 
 typedef void (*shadow_entry_exit_handler_fn)(struct kvm_vcpu *, struct kvm_vcpu *);
 
+static void handle_pvm_entry_wfx(struct kvm_vcpu *host_vcpu, struct kvm_vcpu *shadow_vcpu)
+{
+	shadow_vcpu->arch.flags |= READ_ONCE(host_vcpu->arch.flags) &
+				   KVM_ARM64_INCREMENT_PC;
+}
+
+static void handle_pvm_entry_sys64(struct kvm_vcpu *host_vcpu, struct kvm_vcpu *shadow_vcpu)
+{
+	unsigned long host_flags;
+
+	host_flags = READ_ONCE(host_vcpu->arch.flags);
+
+	/* Exceptions have priority on anything else */
+	if (host_flags & KVM_ARM64_PENDING_EXCEPTION) {
+		/* Exceptions caused by this should be undef exceptions. */
+		u32 esr = (ESR_ELx_EC_UNKNOWN << ESR_ELx_EC_SHIFT);
+
+		__vcpu_sys_reg(shadow_vcpu, ESR_EL1) = esr;
+		shadow_vcpu->arch.flags &= ~(KVM_ARM64_PENDING_EXCEPTION |
+					     KVM_ARM64_EXCEPT_MASK);
+		shadow_vcpu->arch.flags |= (KVM_ARM64_PENDING_EXCEPTION |
+					    KVM_ARM64_EXCEPT_AA64_ELx_SYNC |
+					    KVM_ARM64_EXCEPT_AA64_EL1);
+
+		return;
+	}
+
+	if (host_flags & KVM_ARM64_INCREMENT_PC) {
+		shadow_vcpu->arch.flags &= ~(KVM_ARM64_PENDING_EXCEPTION |
+					     KVM_ARM64_EXCEPT_MASK);
+		shadow_vcpu->arch.flags |= KVM_ARM64_INCREMENT_PC;
+	}
+
+	if (!esr_sys64_to_params(shadow_vcpu->arch.fault.esr_el2).is_write) {
+		/* r0 as transfer register between the guest and the host. */
+		u64 rt_val = READ_ONCE(host_vcpu->arch.ctxt.regs.regs[0]);
+		int rt = kvm_vcpu_sys_get_rt(shadow_vcpu);
+
+		vcpu_set_reg(shadow_vcpu, rt, rt_val);
+	}
+}
+
+static void handle_pvm_entry_iabt(struct kvm_vcpu *host_vcpu, struct kvm_vcpu *shadow_vcpu)
+{
+	unsigned long cpsr = *vcpu_cpsr(shadow_vcpu);
+	unsigned long host_flags;
+	u32 esr = ESR_ELx_IL;
+
+	host_flags = READ_ONCE(host_vcpu->arch.flags);
+
+	if (!(host_flags & KVM_ARM64_PENDING_EXCEPTION))
+		return;
+
+	/*
+	 * If the host wants to inject an exception, get syndrom and
+	 * fault address.
+	 */
+	if ((cpsr & PSR_MODE_MASK) == PSR_MODE_EL0t)
+		esr |= (ESR_ELx_EC_IABT_LOW << ESR_ELx_EC_SHIFT);
+	else
+		esr |= (ESR_ELx_EC_IABT_CUR << ESR_ELx_EC_SHIFT);
+
+	esr |= ESR_ELx_FSC_EXTABT;
+
+	__vcpu_sys_reg(shadow_vcpu, ESR_EL1) = esr;
+	__vcpu_sys_reg(shadow_vcpu, FAR_EL1) = kvm_vcpu_get_hfar(shadow_vcpu);
+
+	/* Tell the run loop that we want to inject something */
+	shadow_vcpu->arch.flags &= ~(KVM_ARM64_PENDING_EXCEPTION |
+				     KVM_ARM64_EXCEPT_MASK);
+	shadow_vcpu->arch.flags |= (KVM_ARM64_PENDING_EXCEPTION |
+				    KVM_ARM64_EXCEPT_AA64_ELx_SYNC |
+				    KVM_ARM64_EXCEPT_AA64_EL1);
+}
+
+static void handle_pvm_entry_dabt(struct kvm_vcpu *host_vcpu, struct kvm_vcpu *shadow_vcpu)
+{
+	unsigned long host_flags;
+	bool rd_update;
+
+	host_flags = READ_ONCE(host_vcpu->arch.flags);
+
+	/* Exceptions have priority over anything else */
+	if (host_flags & KVM_ARM64_PENDING_EXCEPTION) {
+		unsigned long cpsr = *vcpu_cpsr(shadow_vcpu);
+		u32 esr = ESR_ELx_IL;
+
+		if ((cpsr & PSR_MODE_MASK) == PSR_MODE_EL0t)
+			esr |= (ESR_ELx_EC_DABT_LOW << ESR_ELx_EC_SHIFT);
+		else
+			esr |= (ESR_ELx_EC_DABT_CUR << ESR_ELx_EC_SHIFT);
+
+		esr |= ESR_ELx_FSC_EXTABT;
+
+		__vcpu_sys_reg(shadow_vcpu, ESR_EL1) = esr;
+		__vcpu_sys_reg(shadow_vcpu, FAR_EL1) = kvm_vcpu_get_hfar(shadow_vcpu);
+		/* Tell the run loop that we want to inject something */
+		shadow_vcpu->arch.flags &= ~(KVM_ARM64_PENDING_EXCEPTION |
+					     KVM_ARM64_EXCEPT_MASK);
+		shadow_vcpu->arch.flags |= (KVM_ARM64_PENDING_EXCEPTION |
+					    KVM_ARM64_EXCEPT_AA64_ELx_SYNC |
+					    KVM_ARM64_EXCEPT_AA64_EL1);
+
+		/* Cancel potential in-flight MMIO */
+		shadow_vcpu->mmio_needed = false;
+		return;
+	}
+
+	/* Handle PC increment on MMIO */
+	if ((host_flags & KVM_ARM64_INCREMENT_PC) && shadow_vcpu->mmio_needed) {
+		shadow_vcpu->arch.flags &= ~(KVM_ARM64_PENDING_EXCEPTION |
+					     KVM_ARM64_EXCEPT_MASK);
+		shadow_vcpu->arch.flags |= KVM_ARM64_INCREMENT_PC;
+	}
+
+	/* If we were doing an MMIO read access, update the register*/
+	rd_update = (shadow_vcpu->mmio_needed &&
+		     (host_flags & KVM_ARM64_INCREMENT_PC));
+	rd_update &= !kvm_vcpu_dabt_iswrite(shadow_vcpu);
+
+	if (rd_update) {
+		/* r0 as transfer register between the guest and the host. */
+		u64 rd_val = READ_ONCE(host_vcpu->arch.ctxt.regs.regs[0]);
+		int rd = kvm_vcpu_dabt_get_rd(shadow_vcpu);
+
+		vcpu_set_reg(shadow_vcpu, rd, rd_val);
+	}
+
+	shadow_vcpu->mmio_needed = false;
+}
+
+static void handle_pvm_exit_wfx(struct kvm_vcpu *host_vcpu, struct kvm_vcpu *shadow_vcpu)
+{
+	WRITE_ONCE(host_vcpu->arch.ctxt.regs.pstate,
+		   shadow_vcpu->arch.ctxt.regs.pstate & PSR_MODE_MASK);
+	WRITE_ONCE(host_vcpu->arch.fault.esr_el2,
+		   shadow_vcpu->arch.fault.esr_el2);
+}
+
+static void handle_pvm_exit_sys64(struct kvm_vcpu *host_vcpu, struct kvm_vcpu *shadow_vcpu)
+{
+	u32 esr_el2 = shadow_vcpu->arch.fault.esr_el2;
+
+	/* r0 as transfer register between the guest and the host. */
+	WRITE_ONCE(host_vcpu->arch.fault.esr_el2,
+		   esr_el2 & ~ESR_ELx_SYS64_ISS_RT_MASK);
+
+	/* The mode is required for the host to emulate some sysregs */
+	WRITE_ONCE(host_vcpu->arch.ctxt.regs.pstate,
+		   shadow_vcpu->arch.ctxt.regs.pstate & PSR_MODE_MASK);
+
+	if (esr_sys64_to_params(esr_el2).is_write) {
+		int rt = kvm_vcpu_sys_get_rt(shadow_vcpu);
+		u64 rt_val = vcpu_get_reg(shadow_vcpu, rt);
+
+		WRITE_ONCE(host_vcpu->arch.ctxt.regs.regs[0], rt_val);
+	}
+}
+
+static void handle_pvm_exit_iabt(struct kvm_vcpu *host_vcpu, struct kvm_vcpu *shadow_vcpu)
+{
+	WRITE_ONCE(host_vcpu->arch.fault.esr_el2,
+		   shadow_vcpu->arch.fault.esr_el2);
+	WRITE_ONCE(host_vcpu->arch.fault.hpfar_el2,
+		   shadow_vcpu->arch.fault.hpfar_el2);
+}
+
+static void handle_pvm_exit_dabt(struct kvm_vcpu *host_vcpu, struct kvm_vcpu *shadow_vcpu)
+{
+	/*
+	 * For now, we treat all data aborts as MMIO since we have no knowledge
+	 * of the memslot configuration at EL2.
+	 */
+	shadow_vcpu->mmio_needed = true;
+
+	if (shadow_vcpu->mmio_needed) {
+		/* r0 as transfer register between the guest and the host. */
+		WRITE_ONCE(host_vcpu->arch.fault.esr_el2,
+			   shadow_vcpu->arch.fault.esr_el2 & ~ESR_ELx_SRT_MASK);
+
+		if (kvm_vcpu_dabt_iswrite(shadow_vcpu)) {
+			int rt = kvm_vcpu_dabt_get_rd(shadow_vcpu);
+			u64 rt_val = vcpu_get_reg(shadow_vcpu, rt);
+
+			WRITE_ONCE(host_vcpu->arch.ctxt.regs.regs[0], rt_val);
+		}
+	} else {
+		WRITE_ONCE(host_vcpu->arch.fault.esr_el2,
+			   shadow_vcpu->arch.fault.esr_el2 & ~ESR_ELx_ISV);
+	}
+
+	WRITE_ONCE(host_vcpu->arch.ctxt.regs.pstate,
+		   shadow_vcpu->arch.ctxt.regs.pstate & PSR_MODE_MASK);
+	WRITE_ONCE(host_vcpu->arch.fault.far_el2,
+		   shadow_vcpu->arch.fault.far_el2 & GENMASK(11, 0));
+	WRITE_ONCE(host_vcpu->arch.fault.hpfar_el2,
+		   shadow_vcpu->arch.fault.hpfar_el2);
+	WRITE_ONCE(__vcpu_sys_reg(host_vcpu, SCTLR_EL1),
+		   __vcpu_sys_reg(shadow_vcpu, SCTLR_EL1) & (SCTLR_ELx_EE | SCTLR_EL1_E0E));
+}
+
 static void handle_vm_entry_generic(struct kvm_vcpu *host_vcpu, struct kvm_vcpu *shadow_vcpu)
 {
 	unsigned long host_flags = READ_ONCE(host_vcpu->arch.flags);
@@ -67,6 +270,22 @@ static void handle_vm_exit_abt(struct kvm_vcpu *host_vcpu, struct kvm_vcpu *shad
 		   shadow_vcpu->arch.fault.disr_el1);
 }
 
+static const shadow_entry_exit_handler_fn entry_pvm_shadow_handlers[] = {
+	[0 ... ESR_ELx_EC_MAX]		= NULL,
+	[ESR_ELx_EC_WFx]		= handle_pvm_entry_wfx,
+	[ESR_ELx_EC_SYS64]		= handle_pvm_entry_sys64,
+	[ESR_ELx_EC_IABT_LOW]		= handle_pvm_entry_iabt,
+	[ESR_ELx_EC_DABT_LOW]		= handle_pvm_entry_dabt,
+};
+
+static const shadow_entry_exit_handler_fn exit_pvm_shadow_handlers[] = {
+	[0 ... ESR_ELx_EC_MAX]		= NULL,
+	[ESR_ELx_EC_WFx]		= handle_pvm_exit_wfx,
+	[ESR_ELx_EC_SYS64]		= handle_pvm_exit_sys64,
+	[ESR_ELx_EC_IABT_LOW]		= handle_pvm_exit_iabt,
+	[ESR_ELx_EC_DABT_LOW]		= handle_pvm_exit_dabt,
+};
+
 static const shadow_entry_exit_handler_fn entry_vm_shadow_handlers[] = {
 	[0 ... ESR_ELx_EC_MAX]		= handle_vm_entry_generic,
 };
@@ -219,9 +438,13 @@ static void flush_shadow_state(struct kvm_shadow_vcpu_state *shadow_state)
 		break;
 	case ARM_EXCEPTION_TRAP:
 		esr_ec = ESR_ELx_EC(kvm_vcpu_get_esr(shadow_vcpu));
-		ec_handler = entry_vm_shadow_handlers[esr_ec];
+		if (shadow_state_is_protected(shadow_state))
+			ec_handler = entry_pvm_shadow_handlers[esr_ec];
+		else
+			ec_handler = entry_vm_shadow_handlers[esr_ec];
 		if (ec_handler)
 			ec_handler(host_vcpu, shadow_vcpu);
+
 		break;
 	default:
 		BUG();
@@ -251,7 +474,10 @@ static void sync_shadow_state(struct kvm_shadow_vcpu_state *shadow_state,
 		break;
 	case ARM_EXCEPTION_TRAP:
 		esr_ec = ESR_ELx_EC(kvm_vcpu_get_esr(shadow_vcpu));
-		ec_handler = exit_vm_shadow_handlers[esr_ec];
+		if (shadow_state_is_protected(shadow_state))
+			ec_handler = exit_pvm_shadow_handlers[esr_ec];
+		else
+			ec_handler = exit_vm_shadow_handlers[esr_ec];
 		if (ec_handler)
 			ec_handler(host_vcpu, shadow_vcpu);
 		break;
-- 
2.36.1.124.g0e6072fb45-goog


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

  parent reply	other threads:[~2022-05-19 13:46 UTC|newest]

Thread overview: 321+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-19 13:40 [PATCH 00/89] KVM: arm64: Base support for the pKVM hypervisor at EL2 Will Deacon
2022-05-19 13:40 ` Will Deacon
2022-05-19 13:40 ` Will Deacon
2022-05-19 13:40 ` [PATCH 01/89] KVM: arm64: Handle all ID registers trapped for a protected VM Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40 ` [PATCH 02/89] KVM: arm64: Remove redundant hyp_assert_lock_held() assertions Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40 ` [PATCH 03/89] KVM: arm64: Return error from kvm_arch_init_vm() on allocation failure Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-20 15:55   ` Alexandru Elisei
2022-05-20 15:55     ` Alexandru Elisei
2022-05-20 15:55     ` Alexandru Elisei
2022-05-31 16:15     ` Will Deacon
2022-05-31 16:15       ` Will Deacon
2022-05-31 16:15       ` Will Deacon
2022-05-19 13:40 ` [PATCH 04/89] KVM: arm64: Ignore 'kvm-arm.mode=protected' when using VHE Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40 ` [PATCH 05/89] KVM: arm64: Extend comment in has_vhe() Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40 ` [PATCH 06/89] KVM: arm64: Drop stale comment Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40 ` [PATCH 07/89] KVM: arm64: Move hyp refcount manipulation helpers Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40 ` [PATCH 08/89] KVM: arm64: Back hyp_vmemmap for all of memory Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40 ` [PATCH 09/89] KVM: arm64: Unify identifiers used to distinguish host and hypervisor Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40 ` [PATCH 10/89] KVM: arm64: Implement do_donate() helper for donating memory Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40 ` [PATCH 11/89] KVM: arm64: Prevent the donation of no-map pages Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40 ` [PATCH 12/89] KVM: arm64: Add helpers to pin memory shared with hyp Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40 ` [PATCH 13/89] KVM: arm64: Include asm/kvm_mmu.h in nvhe/mem_protect.h Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40 ` [PATCH 14/89] KVM: arm64: Add hyp_spinlock_t static initializer Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40 ` [PATCH 15/89] KVM: arm64: Introduce shadow VM state at EL2 Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40 ` [PATCH 16/89] KVM: arm64: Instantiate VM shadow data from EL1 Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40 ` [PATCH 17/89] KVM: arm64: Make hyp stage-1 refcnt correct on the whole range Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40 ` [PATCH 18/89] KVM: arm64: Factor out private range VA allocation Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40 ` [PATCH 19/89] KVM: arm64: Add pcpu fixmap infrastructure at EL2 Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40 ` [PATCH 20/89] KVM: arm64: Provide I-cache invalidation by VA " Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40 ` [PATCH 21/89] KVM: arm64: Allow non-coallescable pages in a hyp_pool Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40 ` [PATCH 22/89] KVM: arm64: Add generic hyp_memcache helpers Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40 ` [PATCH 23/89] KVM: arm64: Instantiate guest stage-2 page-tables at EL2 Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40 ` [PATCH 24/89] KVM: arm64: Return guest memory from EL2 via dedicated teardown memcache Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:40   ` Will Deacon
2022-05-19 13:41 ` [PATCH 25/89] KVM: arm64: Add flags to struct hyp_page Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 26/89] KVM: arm64: Provide a hypercall for the host to reclaim guest memory Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 27/89] KVM: arm64: Extend memory sharing to allow host-to-guest transitions Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 28/89] KVM: arm64: Consolidate stage-2 init in one function Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 29/89] KVM: arm64: Check for PTE validity when checking for executable/cacheable Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 30/89] KVM: arm64: Do not allow memslot changes after first VM run under pKVM Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 31/89] KVM: arm64: Disallow dirty logging and RO memslots with pKVM Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 32/89] KVM: arm64: Use the shadow vCPU structure in handle___kvm_vcpu_run() Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 33/89] KVM: arm64: Handle guest stage-2 page-tables entirely at EL2 Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-20 16:03   ` Alexandru Elisei
2022-05-20 16:03     ` Alexandru Elisei
2022-05-20 16:03     ` Alexandru Elisei
2022-05-31 16:45     ` Will Deacon
2022-05-31 16:45       ` Will Deacon
2022-05-31 16:45       ` Will Deacon
2022-06-08  1:16       ` Huang, Shaoqin
2022-06-08  1:16         ` Huang, Shaoqin
2022-06-08  1:16         ` Huang, Shaoqin
2022-07-27  9:59         ` Alexandru Elisei
2022-07-27  9:59           ` Alexandru Elisei
2022-07-27  9:59           ` Alexandru Elisei
2022-07-28  6:50           ` Huang, Shaoqin
2022-07-28  6:50             ` Huang, Shaoqin
2022-07-28  6:50             ` Huang, Shaoqin
2022-05-19 13:41 ` [PATCH 34/89] KVM: arm64: Don't access kvm_arm_hyp_percpu_base at EL1 Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 35/89] KVM: arm64: Unmap kvm_arm_hyp_percpu_base from the host Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 36/89] KVM: arm64: Maintain a copy of 'kvm_arm_vmid_bits' at EL2 Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 37/89] KVM: arm64: Explicitly map kvm_vgic_global_state " Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 38/89] KVM: arm64: Don't map host sections in pkvm Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 39/89] KVM: arm64: Extend memory donation to allow host-to-guest transitions Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 40/89] KVM: arm64: Split up nvhe/fixed_config.h Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 41/89] KVM: arm64: Make vcpu_{read, write}_sys_reg available to HYP code Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` [PATCH 41/89] KVM: arm64: Make vcpu_{read,write}_sys_reg " Will Deacon
2022-05-19 13:41 ` [PATCH 42/89] KVM: arm64: Simplify vgic-v3 hypercalls Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 43/89] KVM: arm64: Add the {flush, sync}_vgic_state() primitives Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` [PATCH 43/89] KVM: arm64: Add the {flush,sync}_vgic_state() primitives Will Deacon
2022-05-19 13:41 ` [PATCH 44/89] KVM: arm64: Introduce predicates to check for protected state Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 45/89] KVM: arm64: Add the {flush,sync}_timer_state() primitives Will Deacon
2022-05-19 13:41   ` [PATCH 45/89] KVM: arm64: Add the {flush, sync}_timer_state() primitives Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 46/89] KVM: arm64: Introduce the pkvm_vcpu_{load, put} hypercalls Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` [PATCH 46/89] KVM: arm64: Introduce the pkvm_vcpu_{load,put} hypercalls Will Deacon
2022-05-19 13:41 ` [PATCH 47/89] KVM: arm64: Add current vcpu and shadow_state lookup primitive Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 48/89] KVM: arm64: Skip __kvm_adjust_pc() for protected vcpus Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 49/89] KVM: arm64: Add hyp per_cpu variable to track current physical cpu number Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 50/89] KVM: arm64: Ensure that TLBs and I-cache are private to each vcpu Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 51/89] KVM: arm64: Introduce per-EC entry/exit handlers Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 52/89] KVM: arm64: Introduce lazy-ish state sync for non-protected VMs Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 53/89] KVM: arm64: Lazy host FP save/restore Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 54/89] KVM: arm64: Reduce host/shadow vcpu state copying Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 55/89] KVM: arm64: Do not pass the vcpu to __pkvm_host_map_guest() Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 56/89] KVM: arm64: Check directly whether the vcpu is protected Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 57/89] KVM: arm64: Trap debug break and watch from guest Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 58/89] KVM: arm64: Restrict protected VM capabilities Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 59/89] KVM: arm64: Do not support MTE for protected VMs Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-26 20:08   ` Peter Collingbourne
2022-05-26 20:08     ` Peter Collingbourne
2022-05-26 20:08     ` Peter Collingbourne
2022-05-27  7:55     ` Fuad Tabba
2022-05-27  7:55       ` Fuad Tabba
2022-05-27  7:55       ` Fuad Tabba
2022-06-03  3:00       ` Peter Collingbourne
2022-06-03  3:00         ` Peter Collingbourne
2022-06-03  3:00         ` Peter Collingbourne
2022-06-04  8:26         ` Marc Zyngier
2022-06-04  8:26           ` Marc Zyngier
2022-06-04  8:26           ` Marc Zyngier
2022-06-07  0:20           ` Peter Collingbourne
2022-06-07  0:20             ` Peter Collingbourne
2022-06-07  0:20             ` Peter Collingbourne
2022-06-08 18:41             ` Catalin Marinas
2022-06-08 18:41               ` Catalin Marinas
2022-06-08 18:41               ` Catalin Marinas
2022-06-07  0:42   ` Peter Collingbourne
2022-06-07  0:42     ` Peter Collingbourne
2022-06-07  0:42     ` Peter Collingbourne
2022-06-08  7:40     ` Fuad Tabba
2022-06-08  7:40       ` Fuad Tabba
2022-06-08  7:40       ` Fuad Tabba
2022-06-08 17:39       ` Peter Collingbourne
2022-06-08 17:39         ` Peter Collingbourne
2022-06-08 17:39         ` Peter Collingbourne
2022-05-19 13:41 ` [PATCH 60/89] KVM: arm64: Refactor reset_mpidr to extract its computation Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 61/89] KVM: arm64: Reset sysregs for protected VMs Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 62/89] KVM: arm64: Move pkvm_vcpu_init_traps to shadow vcpu init Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 63/89] KVM: arm64: Fix initializing traps in protected mode Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 64/89] KVM: arm64: Advertise GICv3 sysreg interface to protected guests Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 65/89] KVM: arm64: Force injection of a data abort on NISV MMIO exit Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 66/89] KVM: arm64: Donate memory to protected guests Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` Will Deacon [this message]
2022-05-19 13:41   ` [PATCH 67/89] KVM: arm64: Add EL2 entry/exit handlers for pKVM guests Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 68/89] KVM: arm64: Move vgic state between host and shadow vcpu structures Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 69/89] KVM: arm64: Do not update virtual timer state for protected VMs Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 70/89] KVM: arm64: Refactor kvm_vcpu_enable_ptrauth() for hyp use Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 71/89] KVM: arm64: Initialize shadow vm state at hyp Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 72/89] KVM: arm64: Track the SVE state in the shadow vcpu Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 73/89] KVM: arm64: Add HVC handling for protected guests at EL2 Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 74/89] KVM: arm64: Move pstate reset values to kvm_arm.h Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 75/89] KVM: arm64: Move some kvm_psci functions to a shared header Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 76/89] KVM: arm64: Factor out vcpu_reset code for core registers and PSCI Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 77/89] KVM: arm64: Handle PSCI for protected VMs in EL2 Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 78/89] KVM: arm64: Don't expose TLBI hypercalls after de-privilege Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 79/89] KVM: arm64: Add is_pkvm_initialized() helper Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 80/89] KVM: arm64: Refactor enter_exception64() Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 81/89] KVM: arm64: Inject SIGSEGV on illegal accesses Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 82/89] KVM: arm64: Support TLB invalidation in guest context Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 83/89] KVM: arm64: Avoid BBM when changing only s/w bits in Stage-2 PTE Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41 ` [PATCH 84/89] KVM: arm64: Extend memory sharing to allow guest-to-host transitions Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:41   ` Will Deacon
2022-05-19 13:42 ` [PATCH 85/89] KVM: arm64: Document the KVM/arm64-specific calls in hypercalls.rst Will Deacon
2022-05-19 13:42   ` Will Deacon
2022-05-19 13:42   ` Will Deacon
2022-05-19 13:42 ` [PATCH 86/89] KVM: arm64: Reformat/beautify PTP hypercall documentation Will Deacon
2022-05-19 13:42   ` Will Deacon
2022-05-19 13:42   ` Will Deacon
2022-05-19 13:42 ` [PATCH 87/89] KVM: arm64: Expose memory sharing hypercalls to protected guests Will Deacon
2022-05-19 13:42   ` Will Deacon
2022-05-19 13:42   ` Will Deacon
2022-05-19 13:42 ` [PATCH 88/89] KVM: arm64: Introduce KVM_VM_TYPE_ARM_PROTECTED machine type for PVMs Will Deacon
2022-05-19 13:42   ` Will Deacon
2022-05-19 13:42   ` Will Deacon
2022-05-19 13:42 ` [PATCH 89/89] Documentation: KVM: Add some documentation for Protected KVM on arm64 Will Deacon
2022-05-19 13:42   ` Will Deacon
2022-05-19 13:42   ` Will Deacon
2022-06-07 22:39   ` Peter Collingbourne
2022-06-07 22:39     ` Peter Collingbourne
2022-06-07 22:39     ` Peter Collingbourne

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=20220519134204.5379-68-will@kernel.org \
    --to=will@kernel.org \
    --cc=catalin.marinas@arm.com \
    --cc=chao.p.peng@linux.intel.com \
    --cc=kernel-team@android.com \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.cs.columbia.edu \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=luto@amacapital.net \
    --cc=maz@kernel.org \
    --cc=michael.roth@amd.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 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.