From: Fuad Tabba <fuad.tabba@linux.dev>
To: Marc Zyngier <maz@kernel.org>, Oliver Upton <oupton@kernel.org>
Cc: Will Deacon <will@kernel.org>,
Catalin Marinas <catalin.marinas@arm.com>,
Mark Rutland <mark.rutland@arm.com>,
Paolo Bonzini <pbonzini@redhat.com>,
Sean Christopherson <seanjc@google.com>,
Shuah Khan <shuah@kernel.org>, Joey Gouly <joey.gouly@arm.com>,
Steffen Eiden <seiden@linux.ibm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Zenghui Yu <yuzenghui@huawei.com>,
Vincent Donnefort <vdonnefort@google.com>,
Quentin Perret <qperret@google.com>,
Fuad Tabba <tabba@google.com>,
kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
kvm@vger.kernel.org, linux-kselftest@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: [PATCH v2 12/19] KVM: arm64: selftests: Add pkvm_id_regs register and trap test
Date: Mon, 9 Nov 2026 08:48:47 +0000 [thread overview]
Message-ID: <20261109084854.840576-13-fuad.tabba@linux.dev> (raw)
In-Reply-To: <20261109084854.840576-1-fuad.tabba@linux.dev>
pKVM gives a protected guest its own view of the ID registers,
hiding the features pKVM doesn't support. Their registers UNDEF,
except some hidden debug registers, which are RAZ/WI.
Test that view and those UNDEFs from the guest, and the
registers EL2 emulates with fixed values. The debug checks follow
ID_AA64DFR0_EL1.DebugVer. The PtrAuth and SVE cases run when a
protected VM's fd reports the capability, and the SVE case also
compares ID_AA64ZFR0_EL1 with what host userspace reads.
Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev>
---
tools/testing/selftests/kvm/Makefile.kvm | 1 +
.../selftests/kvm/arm64/pkvm_id_regs.c | 324 ++++++++++++++++++
2 files changed, 325 insertions(+)
create mode 100644 tools/testing/selftests/kvm/arm64/pkvm_id_regs.c
diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm
index 6bb436bd36205..8855c9abb2fd0 100644
--- a/tools/testing/selftests/kvm/Makefile.kvm
+++ b/tools/testing/selftests/kvm/Makefile.kvm
@@ -191,6 +191,7 @@ TEST_GEN_PROGS_arm64 += arm64/external_aborts
TEST_GEN_PROGS_arm64 += arm64/mmio_sign_ext
TEST_GEN_PROGS_arm64 += arm64/page_fault_test
TEST_GEN_PROGS_arm64 += arm64/pkvm_host_abi
+TEST_GEN_PROGS_arm64 += arm64/pkvm_id_regs
TEST_GEN_PROGS_arm64 += arm64/pkvm_mem_share
TEST_GEN_PROGS_arm64 += arm64/pkvm_psci
TEST_GEN_PROGS_arm64 += arm64/pkvm_smccc
diff --git a/tools/testing/selftests/kvm/arm64/pkvm_id_regs.c b/tools/testing/selftests/kvm/arm64/pkvm_id_regs.c
new file mode 100644
index 0000000000000..93ed557a30bc6
--- /dev/null
+++ b/tools/testing/selftests/kvm/arm64/pkvm_id_regs.c
@@ -0,0 +1,324 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * pkvm_id_regs - the ID registers a protected VM sees, and which of its
+ * register accesses UNDEF.
+ *
+ * Copyright (C) 2025 Google LLC
+ * Author: Fuad Tabba <fuad.tabba@linux.dev>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+
+#include "gic_v3.h"
+#include "kvm_util.h"
+#include "pkvm.h"
+#include "processor.h"
+#include "test_util.h"
+
+/* vCPU 0's MPIDR: Aff0=0, bit31=1, MT=0. */
+#define MPIDR_VCPU0 0x80000000UL
+
+/* Hidden fields with a non-zero Not-Implemented encoding. */
+#define PVM_ID_AA64DFR0_NI ( \
+ SYS_FIELD_PREP_ENUM(ID_AA64DFR0_EL1, DoubleLock, NI) | \
+ SYS_FIELD_PREP_ENUM(ID_AA64DFR0_EL1, MTPMU, NI))
+#define PVM_ID_AA64MMFR4_NI SYS_FIELD_PREP_ENUM(ID_AA64MMFR4_EL1, E2H0, NI)
+
+/* What self-hosted debug exposes: DebugVer and the breakpoint, watchpoint and CTX counts. */
+#define PVM_ID_AA64DFR0_DEBUG (ID_AA64DFR0_EL1_DebugVer_MASK | ID_AA64DFR0_EL1_BRPs_MASK | \
+ ID_AA64DFR0_EL1_WRPs_MASK | ID_AA64DFR0_EL1_CTX_CMPs_MASK)
+
+/* Breakpoint and watchpoint 0 controls with E clear: every byte, EL1, loads and stores. */
+#define DBGBCR_VAL ((0xfUL << 5) | (1UL << 1))
+#define DBGWCR_VAL ((0xffUL << 5) | (3UL << 3) | (1UL << 1))
+
+extern unsigned char brk_insn;
+
+static volatile bool undef_seen;
+static volatile u64 brk_pc;
+
+static void undef_handler(struct ex_regs *regs)
+{
+ undef_seen = true;
+ regs->pc += 4;
+}
+
+static void brk_handler(struct ex_regs *regs)
+{
+ brk_pc = regs->pc;
+ regs->pc += 4;
+}
+
+/* Access @expr must make the guest take an UNDEF (EC_UNKNOWN). */
+#define GUEST_ASSERT_UNDEF(expr) do { \
+ undef_seen = false; \
+ expr; \
+ GUEST_ASSERT(undef_seen); \
+} while (0)
+
+/* @reg reads back @pattern with no UNDEF. */
+#define GUEST_ASSERT_RW(reg, pattern) do { \
+ u64 __saved = read_sysreg_s(reg); \
+ undef_seen = false; \
+ write_sysreg_s(pattern, reg); \
+ GUEST_ASSERT_EQ(read_sysreg_s(reg), pattern); \
+ write_sysreg_s(__saved, reg); \
+ GUEST_ASSERT(!undef_seen); \
+} while (0)
+
+static void assert_aarch32_id_raz(void)
+{
+ /* AArch32 is unsupported for protected guests: its ID block reads 0. */
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_ID_PFR0_EL1), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_ID_PFR1_EL1), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_ID_DFR0_EL1), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_ID_AFR0_EL1), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_ID_MMFR0_EL1), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_ID_MMFR1_EL1), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_ID_MMFR2_EL1), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_ID_MMFR3_EL1), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_ID_ISAR0_EL1), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_ID_ISAR1_EL1), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_ID_ISAR2_EL1), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_ID_ISAR3_EL1), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_ID_ISAR4_EL1), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_ID_ISAR5_EL1), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_ID_MMFR4_EL1), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_ID_ISAR6_EL1), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_MVFR0_EL1), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_MVFR1_EL1), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_MVFR2_EL1), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(sys_reg(3, 0, 0, 3, 3)), 0); /* unallocated */
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_ID_PFR2_EL1), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_ID_DFR1_EL1), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_ID_MMFR5_EL1), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(sys_reg(3, 0, 0, 3, 7)), 0); /* unallocated */
+}
+
+/* A zero DebugVer means EL2 hides self-hosted debug from the guest. */
+static bool debug_exposed(void)
+{
+ return SYS_FIELD_GET(ID_AA64DFR0_EL1, DebugVer, read_sysreg_s(SYS_ID_AA64DFR0_EL1));
+}
+
+static void assert_id_regs(void)
+{
+ u64 pfr0 = read_sysreg_s(SYS_ID_AA64PFR0_EL1);
+ u64 dfr0 = read_sysreg_s(SYS_ID_AA64DFR0_EL1);
+
+ if (debug_exposed()) {
+ u64 debugver = SYS_FIELD_GET(ID_AA64DFR0_EL1, DebugVer, dfr0);
+ u64 brps = SYS_FIELD_GET(ID_AA64DFR0_EL1, BRPs, dfr0);
+
+ /* Exposed debug: at most v8.8, and at least two breakpoints and two watchpoints. */
+ GUEST_ASSERT_EQ(dfr0 & ~PVM_ID_AA64DFR0_DEBUG, PVM_ID_AA64DFR0_NI);
+ GUEST_ASSERT(debugver >= ID_AA64DFR0_EL1_DebugVer_IMP);
+ GUEST_ASSERT(debugver <= ID_AA64DFR0_EL1_DebugVer_V8P8);
+ GUEST_ASSERT(brps >= 1);
+ GUEST_ASSERT(SYS_FIELD_GET(ID_AA64DFR0_EL1, WRPs, dfr0) >= 1);
+ GUEST_ASSERT(SYS_FIELD_GET(ID_AA64DFR0_EL1, CTX_CMPs, dfr0) <= brps);
+ } else {
+ /* Debug and PMU are hidden: DFR0 has a fixed value, no breakpoints. */
+ GUEST_ASSERT_EQ(dfr0, PVM_ID_AA64DFR0_NI);
+ }
+
+ /* With no vCPU features, SVE, ZFR0 and PtrAuth read 0. */
+ GUEST_ASSERT_EQ(SYS_FIELD_GET(ID_AA64PFR0_EL1, SVE, pfr0), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_ID_AA64ZFR0_EL1), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_ID_AA64ISAR1_EL1) &
+ (ID_AA64ISAR1_EL1_APA_MASK | ID_AA64ISAR1_EL1_API_MASK |
+ ID_AA64ISAR1_EL1_GPA_MASK | ID_AA64ISAR1_EL1_GPI_MASK), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_ID_AA64ISAR2_EL1) &
+ (ID_AA64ISAR2_EL1_APA3_MASK | ID_AA64ISAR2_EL1_GPA3_MASK), 0);
+
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_ID_AA64DFR1_EL1), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_ID_AA64AFR0_EL1), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_ID_AA64AFR1_EL1), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_ID_AA64SMFR0_EL1), 0);
+ GUEST_ASSERT_EQ(SYS_FIELD_GET(ID_AA64PFR1_EL1, MTE, read_sysreg_s(SYS_ID_AA64PFR1_EL1)), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_ID_AA64MMFR4_EL1), PVM_ID_AA64MMFR4_NI);
+
+ assert_aarch32_id_raz();
+}
+
+static void assert_debug_raz_wi(void)
+{
+ /* Breakpoint/watchpoint 0, MDSCR and OS-lock regs are RAZ/WI, with no UNDEF. */
+ undef_seen = false;
+ write_sysreg_s(~0UL, SYS_DBGBVRn_EL1(0));
+ write_sysreg_s(~0UL, SYS_DBGBCRn_EL1(0));
+ write_sysreg_s(~0UL, SYS_DBGWVRn_EL1(0));
+ write_sysreg_s(~0UL, SYS_DBGWCRn_EL1(0));
+ write_sysreg_s(~0UL, SYS_MDSCR_EL1);
+ write_sysreg_s(~0UL, SYS_OSLAR_EL1);
+ write_sysreg_s(~0UL, SYS_OSDLR_EL1);
+ isb();
+
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_DBGBVRn_EL1(0)), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_DBGBCRn_EL1(0)), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_DBGWVRn_EL1(0)), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_DBGWCRn_EL1(0)), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_MDSCR_EL1), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_OSLSR_EL1), 0);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_OSDLR_EL1), 0);
+ GUEST_ASSERT(!undef_seen);
+
+ /* Breakpoint/watchpoint indices above 0 are not implemented. */
+ GUEST_ASSERT_UNDEF((void)read_sysreg_s(SYS_DBGBVRn_EL1(1)));
+ GUEST_ASSERT_UNDEF((void)read_sysreg_s(SYS_DBGWVRn_EL1(1)));
+}
+
+static void assert_debug_regs(void)
+{
+ u64 addr = (u64)&brk_insn;
+
+ /* Breakpoint/watchpoint 0 hold what the guest writes. */
+ GUEST_ASSERT_RW(SYS_DBGBVRn_EL1(0), addr);
+ GUEST_ASSERT_RW(SYS_DBGBCRn_EL1(0), DBGBCR_VAL);
+ GUEST_ASSERT_RW(SYS_DBGWVRn_EL1(0), addr & ~7UL);
+ GUEST_ASSERT_RW(SYS_DBGWCRn_EL1(0), DBGWCR_VAL);
+
+ /*
+ * MDSCR doesn't UNDEF. The OS lock is implemented. The OS double lock isn't,
+ * so OSDLR is RAZ/WI.
+ */
+ undef_seen = false;
+ write_sysreg_s(read_sysreg_s(SYS_MDSCR_EL1), SYS_MDSCR_EL1);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_OSLSR_EL1) & OSLSR_EL1_OSLM_MASK,
+ OSLSR_EL1_OSLM_IMPLEMENTED);
+ write_sysreg_s(~0UL, SYS_OSDLR_EL1);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_OSDLR_EL1), 0);
+ GUEST_ASSERT(!undef_seen);
+}
+
+static void assert_undef_regs(void)
+{
+ /* The PMU is hidden, and its registers UNDEF. */
+ GUEST_ASSERT_UNDEF((void)read_sysreg_s(SYS_PMCR_EL0));
+ GUEST_ASSERT_UNDEF((void)read_sysreg_s(SYS_PMCNTENSET_EL0));
+ GUEST_ASSERT_UNDEF((void)read_sysreg_s(SYS_PMUSERENR_EL0));
+
+ /* Limited-ordering region registers UNDEF. */
+ GUEST_ASSERT_UNDEF((void)read_sysreg_s(SYS_LORID_EL1));
+
+ /* AMU and MTE are hidden, and so are the PtrAuth keys without the PtrAuth vCPU features. */
+ GUEST_ASSERT_UNDEF((void)read_sysreg_s(SYS_AMCNTENSET0_EL0));
+ GUEST_ASSERT_UNDEF((void)read_sysreg_s(SYS_GCR_EL1));
+ GUEST_ASSERT_UNDEF((void)read_sysreg_s(SYS_APIAKEYLO_EL1));
+
+ /*
+ * Nor is SVE, so an SVE instruction UNDEFs even with CPACR_EL1.ZEN set. On a CPU
+ * with SME but no SVE, SMEN gates it instead, so set that too.
+ */
+ write_sysreg(read_sysreg(cpacr_el1) | CPACR_EL1_ZEN_EL1EN | CPACR_EL1_SMEN_EL1EN,
+ cpacr_el1);
+ isb();
+ GUEST_ASSERT_UNDEF(asm volatile(".arch_extension sve\n rdvl x0, #1" : : : "x0"));
+}
+
+static void assert_host_handled(void)
+{
+ /* Host-handled registers reach the guest with no UNDEF. */
+ undef_seen = false;
+ (void)read_sysreg_s(SYS_CTR_EL0);
+ (void)read_sysreg_s(SYS_CLIDR_EL1);
+ GUEST_ASSERT(!undef_seen);
+}
+
+static void guest_baseline(void)
+{
+ pkvm_guest_init();
+
+ assert_id_regs();
+ if (debug_exposed())
+ assert_debug_regs();
+ else
+ assert_debug_raz_wi();
+ assert_undef_regs();
+ assert_host_handled();
+
+ asm volatile("brk_insn: brk #0");
+ GUEST_ASSERT_EQ(brk_pc, (u64)&brk_insn);
+
+ /* EL2 emulates ICC_SRE_EL1 with a fixed value. */
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_ICC_SRE_EL1),
+ ICC_SRE_EL1_DIB | ICC_SRE_EL1_DFB | ICC_SRE_EL1_SRE);
+
+ GUEST_ASSERT_EQ(read_sysreg(mpidr_el1), MPIDR_VCPU0);
+
+ GUEST_DONE();
+}
+
+/* The host implements one of QARMA5, an IMP DEF algorithm or QARMA3: any may appear. */
+static void guest_ptrauth(void)
+{
+ pkvm_guest_init();
+ GUEST_ASSERT((read_sysreg_s(SYS_ID_AA64ISAR1_EL1) &
+ (ID_AA64ISAR1_EL1_APA_MASK | ID_AA64ISAR1_EL1_API_MASK)) |
+ (read_sysreg_s(SYS_ID_AA64ISAR2_EL1) &
+ (ID_AA64ISAR2_EL1_APA3_MASK | ID_AA64ISAR2_EL1_GPA3_MASK)));
+ GUEST_DONE();
+}
+
+/* Set in the guest's copy by the host: ID_AA64ZFR0_EL1 as host userspace reads it. */
+static u64 host_zfr0;
+
+static void guest_sve(void)
+{
+ pkvm_guest_init();
+ GUEST_ASSERT_EQ(SYS_FIELD_GET(ID_AA64PFR0_EL1, SVE, read_sysreg_s(SYS_ID_AA64PFR0_EL1)),
+ ID_AA64PFR0_EL1_SVE_IMP);
+ GUEST_ASSERT_EQ(read_sysreg_s(SYS_ID_AA64ZFR0_EL1), host_zfr0);
+ GUEST_DONE();
+}
+
+static void run_guest(u32 features, void *guest_code)
+{
+ struct kvm_vcpu *vcpu;
+ struct kvm_vm *vm;
+
+ vm = pkvm_vm_create(1, features, &vcpu);
+ if (features & BIT(KVM_ARM_VCPU_SVE)) {
+ int feature = KVM_ARM_VCPU_SVE;
+
+ vcpu_ioctl(vcpu, KVM_ARM_VCPU_FINALIZE, &feature);
+ host_zfr0 = read_sysreg_s(SYS_ID_AA64ZFR0_EL1);
+ sync_global_to_guest(vm, host_zfr0);
+ }
+ vm_install_sync_handler(vm, VECTOR_SYNC_CURRENT, ESR_ELx_EC_UNKNOWN, undef_handler);
+ vm_install_sync_handler(vm, VECTOR_SYNC_CURRENT, ESR_ELx_EC_BRK64, brk_handler);
+
+ pkvm_vcpu_setup_boot(vcpu, guest_code);
+ pkvm_run_loop(vcpu, NULL);
+ kvm_vm_free(vm);
+}
+
+int main(void)
+{
+ TEST_REQUIRE(pkvm_supported());
+
+ ksft_print_header();
+ ksft_set_plan(3);
+
+ run_guest(0, guest_baseline);
+ ksft_test_result_pass("baseline ID view and UNDEF matrix\n");
+
+ if (pkvm_has_cap(KVM_CAP_ARM_SVE)) {
+ run_guest(BIT(KVM_ARM_VCPU_SVE), guest_sve);
+ ksft_test_result_pass("SVE ID delta\n");
+ } else {
+ ksft_test_result_skip("SVE ID delta: SVE unavailable to a protected VM\n");
+ }
+
+ if (pkvm_has_cap(KVM_CAP_ARM_PTRAUTH_ADDRESS) &&
+ pkvm_has_cap(KVM_CAP_ARM_PTRAUTH_GENERIC)) {
+ run_guest(BIT(KVM_ARM_VCPU_PTRAUTH_ADDRESS) |
+ BIT(KVM_ARM_VCPU_PTRAUTH_GENERIC), guest_ptrauth);
+ ksft_test_result_pass("PtrAuth ID delta\n");
+ } else {
+ ksft_test_result_skip("PtrAuth ID delta: PtrAuth unavailable\n");
+ }
+
+ ksft_finished();
+}
--
2.47.3
next prev parent reply other threads:[~2026-11-09 8:49 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-09 8:48 [PATCH v2 00/19] KVM: arm64: selftests: Tests for protected VMs Fuad Tabba
2026-11-09 8:48 ` [PATCH v2 01/19] KVM: arm64: Hide generic ptrauth from protected VMs without ptrauth Fuad Tabba
2026-11-09 8:48 ` [PATCH v2 02/19] KVM: arm64: selftests: Inject an abort before a vCPU's first run Fuad Tabba
2026-11-09 8:48 ` [PATCH v2 03/19] KVM: selftests: Allow arm64 tests to create protected VMs Fuad Tabba
2026-11-09 8:48 ` [PATCH v2 04/19] tools: arm-smccc: Add the pKVM memory sharing function IDs Fuad Tabba
2026-11-09 8:48 ` [PATCH v2 05/19] KVM: selftests: Export the ucall pool's guest physical address Fuad Tabba
2026-11-09 8:48 ` [PATCH v2 06/19] KVM: arm64: selftests: Add protected-VM boot trampoline Fuad Tabba
2026-11-09 8:48 ` [PATCH v2 07/19] KVM: arm64: selftests: Add protected-VM library helpers Fuad Tabba
2026-11-09 8:48 ` [PATCH v2 08/19] KVM: arm64: selftests: Add pkvm_host_abi host-interface test Fuad Tabba
2026-11-09 8:48 ` [PATCH v2 09/19] KVM: arm64: selftests: Add pkvm_psci multi-vCPU PSCI test Fuad Tabba
2026-11-09 8:48 ` [PATCH v2 10/19] KVM: arm64: selftests: Add pkvm_mem_share hypercall test Fuad Tabba
2026-11-09 8:48 ` [PATCH v2 11/19] KVM: arm64: selftests: Add pkvm_smccc " Fuad Tabba
2026-11-09 8:48 ` Fuad Tabba [this message]
2026-11-09 8:48 ` [PATCH v2 13/19] KVM: arm64: selftests: Add pkvm_vcpu_regs register-state test Fuad Tabba
2026-11-09 8:48 ` [PATCH v2 14/19] KVM: arm64: selftests: Add pkvm_irq interrupt test Fuad Tabba
2026-11-09 8:48 ` [PATCH v2 15/19] KVM: arm64: selftests: Add pkvm_isolation host-access test Fuad Tabba
2026-11-09 8:48 ` [PATCH v2 16/19] KVM: arm64: selftests: Add pkvm_lifecycle teardown test Fuad Tabba
2026-11-09 8:48 ` [PATCH v2 17/19] KVM: arm64: selftests: Add pkvm_exceptions debug and SError test Fuad Tabba
2026-11-09 8:48 ` [PATCH v2 18/19] KVM: arm64: selftests: Add pkvm_sve vector-length test Fuad Tabba
2026-11-09 8:48 ` [PATCH v2 19/19] KVM: arm64: selftests: Check MOPS, PIE, POE and FPMR in a protected VM Fuad Tabba
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=20261109084854.840576-13-fuad.tabba@linux.dev \
--to=fuad.tabba@linux.dev \
--cc=catalin.marinas@arm.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-kselftest@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=maz@kernel.org \
--cc=oupton@kernel.org \
--cc=pbonzini@redhat.com \
--cc=qperret@google.com \
--cc=seanjc@google.com \
--cc=seiden@linux.ibm.com \
--cc=shuah@kernel.org \
--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 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.