From: Leonardo Bras <leo.bras@arm.com>
To: Mark Brown <broonie@kernel.org>
Cc: Leonardo Bras <leo.bras@arm.com>,
Catalin Marinas <catalin.marinas@arm.com>,
Will Deacon <will@kernel.org>, Marc Zyngier <maz@kernel.org>,
Joey Gouly <joey.gouly@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Shuah Khan <shuah@kernel.org>, Oliver Upton <oupton@kernel.org>,
Fuad Tabba <fuad.tabba@linux.dev>,
Peter Maydell <peter.maydell@linaro.org>,
Wei-Lin Chang <weilin.chang@arm.com>,
Yao Yuan <yaoyuan@linux.alibaba.com>,
linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org,
kvmarm@lists.linux.dev, linux-kselftest@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH v20 14/14] KVM: selftests: arm64: Add GCS EXLOCK exception emulation test
Date: Thu, 10 Sep 2026 18:20:30 +0100 [thread overview]
Message-ID: <aqLm3qT755sXH_D9@LeoBrasDK> (raw)
In-Reply-To: <20260901-arm64-gcs-v20-14-f31750bdfadb@kernel.org>
On Tue, Sep 01, 2026 at 10:47:12PM +0100, Mark Brown wrote:
> When running in vEL2 ERET is emulated, this means that we must emulate
> the behaviour of GCSCR_EL2.EXLOCKEN. Add a test that validates the
> behaviour.
>
> As per DDI0487 R_WTXBY PSTATE.EXLOCK is set to the value of
> GCSCR_ELx.EXLOCKEN when taking an exception to the same exception level.
> As per DDI0487 R_TYTWB if on exception return to the same EL
> GCSCR_ELx.EXLOCKEN is 1 and PSTATE.EXLOCK is not 1 then the exception
> return is illegal.
>
> We nest handling of two UDFs to allow us to both observe and modify
> PSTATE.EXLOCK, checking that expected exceptions are generated for ERET.
> We also repeat the UDF tests having enabled fine grained traps for ERET
> to try to ensure that the slow paths are taken.
>
> We also attempt to write to both SPSR_ELx and ELR_ELx, again using a UDF
> handler to control PSTATE.EXLOCK. We do all this both with and without
> having enabled EXLOCKEN, though only for code running at EL2 due to
> framework limitations.
>
> For completeness we also inject a data abort from EL0 to EL2 with
> GCSCR_EL2.EXLOCKEN set, ensuring that PSTATE.EXLOCK is not set.
>
> Signed-off-by: Mark Brown <broonie@kernel.org>
> ---
> tools/testing/selftests/kvm/Makefile.kvm | 1 +
> tools/testing/selftests/kvm/arm64/gcs_exceptions.c | 346 +++++++++++++++++++++
> 2 files changed, 347 insertions(+)
>
Hi Mark,
Maybe because I am new to this type of selftest (i.e. the helpers), or
maybe because I don't understand some of the used mechanisms here, but this
selftest felt hard to understand, even though the commit message made
it sound very simple.
So I will try to cover what I could understand, so please let me know if I
got something wrong.
From both tests, the lower_el() one is the simplest: if the features are
there, you set TGE, EXLOCKEN and EXLOCK, and then do an KVM_SET_VCPU_EVENTS
ioctl which injects a dabt and commit_pending_events(). It should change
the PSTATE which you read and make sure EXLOCK=0.
(This should be about the last sentence in your commit msg)
For same_el(), 3 exception handlers are assigned to the vcpu: unknown,
ilegal, and GCS. You then run the guest once, and exit. Then you check the
exit reason.
In the guest code, you run a few tests for EXTLOCK={0,1} by basically
counting and checking how many times each handler was called, and if the
expected EXLOCK/EXLOCKEN states are correct. (Relying on R_WTXBY)
When you run test_udf_exception() it will cause an udf(COLLECT) that will
itself cause an udf(VALIDATE), and if EXLOCKEN=1, it will cause an illegal
exception, which will by itself cause an udf(REPAIR). On EXLOCKEN=0,
setting EXLOCK=0 should not take an exception, and thus there should be no
illegal++, an just 2 undef. None should cause a gcs exception.
That makes sense with the tests you do after the udf, as well as deciding
to check IL based on EXLOCKEN status.
As for test_sysreg(), it will run for 4 tested registers with both EXLOCKEN
states. What it does it take an udf(reg), which will read then write that
read value to that register. If EXLOCKEN=1 it's expected to cause a gcs
fault. That makes sense with the gcs and udf counters check in the bottom.
The part of re-running test_udf_exception() with HFGITR_EL2 set, IIUC, it
that part of fine-grained traps. It seems correct, although I am not seeing
any tests of the EC syndrome being 0x1A to make sure it's in use.
There are also a lot of expect_exlock being used as an int, even if it's a
bool. I understand the idea of summing it as we expect it to be 1 on true
or 0 on false, but is it really ok?
Maybe we could change it to int, so we just set it when we enter
test_sysreg() or test_udf_exception() like:
- expect_exlock = enable_exlock;
+ expect_exlock = enable_exlock ? 1 : 0;
If I got the workings right, and both above suggestions (0x1A and
bool->int) are either fixed or considered not an issue, then:
Reviewed-by: Leonardo Bras <leo.bras@arm.com>
Thanks!
Leo
> diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm
> index 96bab7002d39..0286453ab223 100644
> --- a/tools/testing/selftests/kvm/Makefile.kvm
> +++ b/tools/testing/selftests/kvm/Makefile.kvm
> @@ -179,6 +179,7 @@ TEST_GEN_PROGS_arm64 += arm64/hello_el2
> TEST_GEN_PROGS_arm64 += arm64/host_sve
> TEST_GEN_PROGS_arm64 += arm64/hypercalls
> TEST_GEN_PROGS_arm64 += arm64/external_aborts
> +TEST_GEN_PROGS_arm64 += arm64/gcs_exceptions
> TEST_GEN_PROGS_arm64 += arm64/mmio_sign_ext
> TEST_GEN_PROGS_arm64 += arm64/page_fault_test
> TEST_GEN_PROGS_arm64 += arm64/psci_test
> diff --git a/tools/testing/selftests/kvm/arm64/gcs_exceptions.c b/tools/testing/selftests/kvm/arm64/gcs_exceptions.c
> new file mode 100644
> index 000000000000..de5bc6590727
> --- /dev/null
> +++ b/tools/testing/selftests/kvm/arm64/gcs_exceptions.c
> @@ -0,0 +1,346 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Test KVM's handling of Guarded Control Stack exception state.
> + */
> +
> +#include "kvm_util.h"
> +#include "processor.h"
> +#include "test_util.h"
> +#include "ucall.h"
> +
> +#include <asm/ptrace.h>
> +#include <asm/sysreg.h>
> +
> +#define PSTATE_IL_BIT BIT(20)
> +
> +static void require_guest_gcs(struct kvm_vcpu *vcpu)
> +{
> + u64 pfr1 = vcpu_get_reg(vcpu,
> + KVM_ARM64_SYS_REG(SYS_ID_AA64PFR1_EL1));
> +
> + TEST_REQUIRE(SYS_FIELD_GET(ID_AA64PFR1_EL1, GCS, pfr1) >=
> + ID_AA64PFR1_EL1_GCS_IMP);
> +}
> +
> +static bool expect_exlock;
> +static unsigned int undef_count;
> +static unsigned int illegal_count;
> +static unsigned int gcs_count;
> +static u64 handler_pstate;
> +static u64 illegal_pstate;
> +
> +static u64 expected_illegal_pc;
> +static enum udf_mode {
> + UDF_COLLECT, /* Initial UDF we collect PSTATE from */
> + UDF_VALIDATE, /* Secondary UDF that collects and validates */
> + UDF_REPAIR, /* UDF to clear EXLOCK */
> + UDF_ELR_EL1, /* Write to ELR_EL1 with EXLOCK */
> + UDF_ELR_EL2, /* Write to ELR_EL2 with EXLOCK */
> + UDF_SPSR_EL1, /* Write to SPSR_EL1 with EXLOCK */
> + UDF_SPSR_EL2, /* Write to SPSR_EL2 with EXLOCK */
> +} udf_mode;
> +
> +static void guest_undef_handler(struct ex_regs *regs)
> +{
> + u64 esr = read_sysreg(esr_el2);
> + u64 val;
> +
> + undef_count++;
> +
> + /* Just skip the instruction either way. */
> + GUEST_ASSERT_EQ(esr, ESR_ELx_IL);
> + regs->pc += 4;
> +
> + switch (udf_mode) {
> + case UDF_COLLECT:
> + GUEST_ASSERT_EQ(read_sysreg_s(SYS_GCSCR_EL2) & GCSCR_ELx_EXLOCKEN,
> + expect_exlock ? GCSCR_ELx_EXLOCKEN : 0);
> +
> + /*
> + * If we want the nested exception handler to change
> + * PSTATE it can't have EXLOCK set.
> + */
> + write_sysreg_s(0, SYS_GCSCR_EL2);
> + isb();
> +
> + /*
> + * Take another exception without returning so we can
> + * collect the EXLOCK state we're seeing here and make
> + * our return illegal.
> + */
> + expected_illegal_pc = regs->pc;
> + udf_mode = UDF_VALIDATE;
> + asm volatile("udf #0" ::: "memory");
> +
> + /* Reenable so PSTATE.EXLOCK is checked */
> + write_sysreg_s(expect_exlock ? GCSCR_ELx_EXLOCKEN : 0,
> + SYS_GCSCR_EL2);
> + isb();
> + break;
> +
> + case UDF_VALIDATE:
> + GUEST_ASSERT_EQ(read_sysreg_s(SYS_GCSCR_EL2) & GCSCR_ELx_EXLOCKEN,
> + 0);
> +
> + /* Validate the EXLOCK of the original exception. */
> + handler_pstate = regs->pstate;
> + GUEST_ASSERT_EQ(!!(regs->pstate & PSR_EXLOCK_BIT),
> + expect_exlock);
> +
> + /* Clearing PSTATE.EXLOCK triggers an illegal ERET. */
> + regs->pstate &= ~PSR_EXLOCK_BIT;
> + break;
> +
> + case UDF_REPAIR:
> + GUEST_ASSERT_EQ(read_sysreg_s(SYS_GCSCR_EL2) & GCSCR_ELx_EXLOCKEN,
> + 0);
> +
> + /* Disable EXLOCK for the requesting context */
> + regs->pstate &= ~PSR_EXLOCK_BIT;
> + break;
> +
> + case UDF_ELR_EL1:
> + GUEST_ASSERT_EQ(read_sysreg_s(SYS_GCSCR_EL2) & GCSCR_ELx_EXLOCKEN,
> + expect_exlock ? GCSCR_ELx_EXLOCKEN : 0);
> +
> + asm volatile("mrs %0, elr_el1 \n\
> + msr elr_el1, %0"
> + : "=r"(val) :: "memory");
> + break;
> +
> + case UDF_ELR_EL2:
> + GUEST_ASSERT_EQ(read_sysreg_s(SYS_GCSCR_EL2) & GCSCR_ELx_EXLOCKEN,
> + expect_exlock ? GCSCR_ELx_EXLOCKEN : 0);
> +
> + asm volatile("mrs %0, elr_el2 \n\
> + msr elr_el2, %0"
> + : "=r"(val) :: "memory");
> + break;
> +
> + case UDF_SPSR_EL1:
> + GUEST_ASSERT_EQ(read_sysreg_s(SYS_GCSCR_EL2) & GCSCR_ELx_EXLOCKEN,
> + expect_exlock ? GCSCR_ELx_EXLOCKEN : 0);
> +
> + asm volatile("mrs %0, spsr_el1 \n\
> + msr spsr_el1, %0"
> + : "=r"(val) :: "memory");
> + break;
> +
> + case UDF_SPSR_EL2:
> + GUEST_ASSERT_EQ(read_sysreg_s(SYS_GCSCR_EL2) & GCSCR_ELx_EXLOCKEN,
> + expect_exlock ? GCSCR_ELx_EXLOCKEN : 0);
> +
> + asm volatile("mrs %0, spsr_el2 \n\
> + msr spsr_el2, %0"
> + : "=r"(val) :: "memory");
> + break;
> +
> + default:
> + GUEST_FAIL("Invalid udf_mode");
> + }
> +}
> +
> +static void guest_illegal_handler(struct ex_regs *regs)
> +{
> + u64 esr = read_sysreg(esr_el2);
> +
> + illegal_count++;
> + illegal_pstate = regs->pstate;
> +
> + GUEST_ASSERT_EQ(ESR_ELx_EC(esr), ESR_ELx_EC_ILL);
> + GUEST_ASSERT(esr & ESR_ELx_IL);
> + GUEST_ASSERT(regs->pstate & PSTATE_IL_BIT);
> + GUEST_ASSERT(!(regs->pstate & PSR_EXLOCK_BIT));
> + GUEST_ASSERT_EQ(regs->pc, expected_illegal_pc);
> +
> + /* Disable exception locking so we can repair the return state. */
> + write_sysreg_s(0, SYS_GCSCR_EL2);
> + isb();
> +
> + /* We need our own EXLOCK clearing so we can repair the original */
> + udf_mode = UDF_REPAIR;
> + asm volatile("udf #0" ::: "memory");
> +
> + /* Disable EXLOCK for the generating context, making things legal */
> + regs->pstate &= ~(PSTATE_IL_BIT | PSR_EXLOCK_BIT);
> +}
> +
> +static void guest_gcs_handler(struct ex_regs *regs)
> +{
> + u64 esr = read_sysreg(esr_el2);
> +
> + gcs_count++;
> +
> + GUEST_ASSERT_EQ(ESR_ELx_EC(esr), ESR_ELx_EC_GCS);
> + GUEST_ASSERT_EQ(FIELD_GET(ESR_ELx_ExType_MASK, esr),
> + ESR_ELx_ExType_EXLOCK);
> +
> + /* Disabling EXLOCKEN makes sysreg writes legal. */
> + write_sysreg_s(0, SYS_GCSCR_EL2);
> + isb();
> +}
> +
> +static noinline void test_udf_exception(bool enable_exlock)
> +{
> + unsigned int initial_undef = undef_count;
> + unsigned int initial_illegal = illegal_count;
> + unsigned int initial_gcs = gcs_count;
> +
> + expect_exlock = enable_exlock;
> + write_sysreg_s(enable_exlock ? GCSCR_ELx_EXLOCKEN : 0,
> + SYS_GCSCR_EL2);
> + isb();
> +
> + udf_mode = UDF_COLLECT;
> + asm volatile("udf #0" ::: "memory");
> +
> + /* Leave GCS disabled even if a broken ERET skipped the ILL handler. */
> + write_sysreg_s(0, SYS_GCSCR_EL2);
> + isb();
> +
> + GUEST_ASSERT_EQ(undef_count, initial_undef + 2 + enable_exlock);
> + GUEST_ASSERT_EQ(illegal_count, initial_illegal + enable_exlock);
> + GUEST_ASSERT_EQ(!!(handler_pstate & PSR_EXLOCK_BIT), enable_exlock);
> + if (enable_exlock)
> + GUEST_ASSERT(illegal_pstate & PSTATE_IL_BIT);
> + GUEST_ASSERT_EQ(initial_gcs, gcs_count);
> +}
> +
> +static noinline void test_sysreg(enum udf_mode reg, bool enable_exlock)
> +{
> + unsigned int initial_undef = undef_count;
> + unsigned int initial_gcs = gcs_count;
> +
> + expect_exlock = enable_exlock;
> +
> + write_sysreg_s(enable_exlock ? GCSCR_ELx_EXLOCKEN : 0,
> + SYS_GCSCR_EL2);
> + isb();
> +
> + udf_mode = reg;
> + asm volatile("udf #0" ::: "memory");
> +
> + /* Ensure EXLOCK is disabled */
> + write_sysreg_s(0, SYS_GCSCR_EL2);
> + isb();
> +
> + GUEST_ASSERT_EQ(gcs_count, initial_gcs + expect_exlock);
> + GUEST_ASSERT_EQ(undef_count, initial_undef + 1);
> +}
> +
> +static void guest_code(void)
> +{
> + GUEST_ASSERT_EQ(get_current_el(), 2);
> +
> + /*
> + * Try straightforwardly generating an exception without and
> + * with EXLOCK.
> + */
> + test_udf_exception(false);
> + test_sysreg(UDF_ELR_EL1, false);
> + test_sysreg(UDF_ELR_EL2, false);
> + test_sysreg(UDF_SPSR_EL1, false);]
> + test_sysreg(UDF_SPSR_EL2, false);
> +
> + test_udf_exception(true);
> + test_sysreg(UDF_ELR_EL1, true);
> + test_sysreg(UDF_ELR_EL2, true);
> + test_sysreg(UDF_SPSR_EL1, true);
> + test_sysreg(UDF_SPSR_EL2, true);
> +
> + /* Force ERET directly through the slow emulation path as well. */
> + sysreg_clear_set_s(SYS_HFGITR_EL2, 0, HFGITR_EL2_ERET);
> + isb();
> +
> + test_udf_exception(false);
> +
> + test_udf_exception(true);
> +
> + sysreg_clear_set_s(SYS_HFGITR_EL2, HFGITR_EL2_ERET, 0);
> + isb();
> + GUEST_DONE();
> +}
> +
> +static void test_exception_from_same_el(void)
> +{
> + struct kvm_vcpu_init init;
> + struct kvm_vcpu *vcpu;
> + struct kvm_vm *vm;
> + struct ucall uc;
> +
> + vm = vm_create(1);
> + kvm_get_default_vcpu_target(vm, &init);
> + init.features[0] |= BIT(KVM_ARM_VCPU_HAS_EL2);
> + vcpu = aarch64_vcpu_add(vm, 0, &init, guest_code);
> + require_guest_gcs(vcpu);
> +
> + vm_init_descriptor_tables(vm);
> + vcpu_init_descriptor_tables(vcpu);
> + vm_install_sync_handler(vm, VECTOR_SYNC_CURRENT,
> + ESR_ELx_EC_UNKNOWN, guest_undef_handler);
> + vm_install_sync_handler(vm, VECTOR_SYNC_CURRENT,
> + ESR_ELx_EC_ILL, guest_illegal_handler);
> + vm_install_sync_handler(vm, VECTOR_SYNC_CURRENT,
> + ESR_ELx_EC_GCS, guest_gcs_handler);
> + kvm_arch_vm_finalize_vcpus(vm);
> +
> + vcpu_run(vcpu);
> + switch (get_ucall(vcpu, &uc)) {
> + case UCALL_DONE:
> + break;
> + case UCALL_ABORT:
> + REPORT_GUEST_ASSERT(uc);
> + break;
> + default:
> + TEST_FAIL("Unhandled ucall: %ld", uc.cmd);
> + }
> +
> + kvm_vm_free(vm);
> +}
> +
> +static void test_exception_from_lower_el(void)
> +{
> + struct kvm_vcpu_events events = {};
> + struct kvm_vcpu_init init;
> + struct kvm_vcpu *vcpu;
> + struct kvm_vm *vm;
> + u64 pstate;
> +
> + vm = vm_create(1);
> + kvm_get_default_vcpu_target(vm, &init);
> + init.features[0] |= BIT(KVM_ARM_VCPU_HAS_EL2);
> + vcpu = aarch64_vcpu_add(vm, 0, &init, NULL);
> + require_guest_gcs(vcpu);
> + kvm_arch_vm_finalize_vcpus(vm);
> +
> + /*
> + * Inject an EL0 data abort to vEL2 with EXLOCK enabled for
> + * vEL2.
> + */
> + vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_HCR_EL2),
> + vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_HCR_EL2)) |
> + HCR_EL2_TGE);
> + vcpu_set_reg(vcpu, KVM_ARM64_SYS_REG(SYS_GCSCR_EL2),
> + GCSCR_ELx_EXLOCKEN);
> + vcpu_set_reg(vcpu, ARM64_CORE_REG(regs.pstate),
> + PSR_MODE_EL0t | PSR_EXLOCK_BIT);
> +
> + events.exception.ext_dabt_pending = true;
> + vcpu_events_set(vcpu, &events);
> +
> + pstate = vcpu_get_reg(vcpu, ARM64_CORE_REG(regs.pstate));
> + TEST_ASSERT_EQ(pstate & PSR_MODE_MASK, PSR_MODE_EL2h);
> + TEST_ASSERT(!(pstate & PSR_EXLOCK_BIT),
> + "EXLOCK set on exception from a lower EL");
> +
> + kvm_vm_free(vm);
> +}
> +
> +int main(void)
> +{
> + TEST_REQUIRE(kvm_check_cap(KVM_CAP_ARM_EL2));
> + test_exception_from_same_el();
> + test_exception_from_lower_el();
> +
> + return 0;
> +}
>
> --
> 2.47.3
>
next prev parent reply other threads:[~2026-09-10 17:20 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-01 21:46 [PATCH v20 00/14] KVM: arm64: Provide guest support for GCS Mark Brown
2026-09-01 21:46 ` [PATCH v20 01/14] arm64/gcs: Ensure FGTs for EL1 GCS instructions are disabled Mark Brown
2026-09-03 16:10 ` Lorenzo Stoakes (ARM)
2026-09-01 21:47 ` [PATCH v20 02/14] KVM: arm64: Fix FGT mapping for HFGITR_EL2.nGCSEPP Mark Brown
2026-09-03 16:23 ` Lorenzo Stoakes (ARM)
2026-09-03 19:29 ` Mark Brown
2026-09-01 21:47 ` [PATCH v20 03/14] KVM: arm64: Manage GCS access and registers for guests Mark Brown
2026-09-02 16:44 ` Leonardo Bras
2026-09-03 20:52 ` Mark Brown
2026-09-03 18:13 ` Lorenzo Stoakes (ARM)
2026-09-03 20:41 ` Mark Brown
2026-09-04 8:54 ` Lorenzo Stoakes (ARM)
2026-09-04 21:07 ` Mark Brown
2026-09-07 14:14 ` Lorenzo Stoakes (ARM)
2026-09-07 14:55 ` Mark Brown
2026-09-09 11:34 ` Lorenzo Stoakes (ARM)
2026-09-01 21:47 ` [PATCH v20 04/14] KVM: arm64: Ensure GCS memory effects are visible Mark Brown
2026-09-02 16:30 ` Leonardo Bras
2026-09-04 12:16 ` Lorenzo Stoakes (ARM)
2026-09-01 21:47 ` [PATCH v20 05/14] KVM: arm64: Set PSTATE.EXLOCK when entering an exception Mark Brown
2026-09-03 14:25 ` Leonardo Bras
2026-09-03 16:20 ` Mark Brown
2026-09-03 16:40 ` Leonardo Bras
2026-09-04 13:04 ` Lorenzo Stoakes (ARM)
2026-09-01 21:47 ` [PATCH v20 06/14] KVM: arm64: Validate GCS exception lock when emulating ERET Mark Brown
2026-09-03 15:37 ` Leonardo Bras
2026-09-03 19:22 ` Mark Brown
2026-09-04 13:16 ` Leonardo Bras
2026-09-04 21:56 ` Mark Brown
2026-09-07 10:55 ` Leonardo Bras
2026-09-01 21:47 ` [PATCH v20 07/14] KVM: arm64: Forward GCS exceptions to nested guests Mark Brown
2026-09-09 13:00 ` Leonardo Bras
2026-09-01 21:47 ` [PATCH v20 08/14] KVM: arm64: Enforce EXLOCK for SPSR and ELR Mark Brown
2026-09-09 14:35 ` Leonardo Bras
2026-09-01 21:47 ` [PATCH v20 09/14] KVM: arm64: Allow GCS to be enabled for guests Mark Brown
2026-09-09 16:34 ` Leonardo Bras
2026-09-09 16:45 ` Mark Brown
2026-09-01 21:47 ` [PATCH v20 10/14] KVM: selftests: arm64: Add GCS registers to get-reg-list Mark Brown
2026-09-09 16:46 ` Leonardo Bras
2026-09-01 21:47 ` [PATCH v20 11/14] KVM: selftests: arm64: Add GCS to set_id_regs Mark Brown
2026-09-09 16:55 ` Leonardo Bras
2026-09-01 21:47 ` [PATCH v20 12/14] KVM: selftests: arm64: Only restore SPSR_EL1 and ELR_EL1 if they change Mark Brown
2026-09-09 17:03 ` Leonardo Bras
2026-09-01 21:47 ` [PATCH v20 13/14] tools: Synchronise the kernel esr.h Mark Brown
2026-09-10 11:10 ` Leonardo Bras
2026-09-01 21:47 ` [PATCH v20 14/14] KVM: selftests: arm64: Add GCS EXLOCK exception emulation test Mark Brown
2026-09-10 17:20 ` Leonardo Bras [this message]
2026-09-10 18:26 ` Mark Brown
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=aqLm3qT755sXH_D9@LeoBrasDK \
--to=leo.bras@arm.com \
--cc=broonie@kernel.org \
--cc=catalin.marinas@arm.com \
--cc=fuad.tabba@linux.dev \
--cc=joey.gouly@arm.com \
--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=maz@kernel.org \
--cc=oupton@kernel.org \
--cc=peter.maydell@linaro.org \
--cc=shuah@kernel.org \
--cc=suzuki.poulose@arm.com \
--cc=weilin.chang@arm.com \
--cc=will@kernel.org \
--cc=yaoyuan@linux.alibaba.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