From: Janosch Frank <frankja@linux.ibm.com>
To: kvm@vger.kernel.org
Cc: linux-s390@vger.kernel.org, imbrenda@linux.ibm.com,
borntraeger@linux.ibm.com
Subject: [PATCH 2/2] KVM: s390: selftests: Add load psw bear test
Date: Mon, 23 Mar 2026 15:35:23 +0000 [thread overview]
Message-ID: <20260323153637.3683-3-frankja@linux.ibm.com> (raw)
In-Reply-To: <20260323153637.3683-1-frankja@linux.ibm.com>
The bear is set for lpsw and lpswe but not for lpswey.
Load PSW and all of its variants are only emulated by KVM if there's a
pending machine check. Therefore the tests inject those but never open
the masks to receive them.
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
---
tools/testing/selftests/kvm/Makefile.kvm | 1 +
tools/testing/selftests/kvm/s390/bear.c | 184 +++++++++++++++++++++++
2 files changed, 185 insertions(+)
create mode 100644 tools/testing/selftests/kvm/s390/bear.c
diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm
index 6471fa214a9f..9afb6479dbee 100644
--- a/tools/testing/selftests/kvm/Makefile.kvm
+++ b/tools/testing/selftests/kvm/Makefile.kvm
@@ -207,6 +207,7 @@ TEST_GEN_PROGS_s390 += s390/user_operexec
TEST_GEN_PROGS_s390 += s390/keyop
TEST_GEN_PROGS_s390 += rseq_test
TEST_GEN_PROGS_s390 += s390/irq_routing
+TEST_GEN_PROGS_s390 += s390/bear
TEST_GEN_PROGS_riscv = $(TEST_GEN_PROGS_COMMON)
TEST_GEN_PROGS_riscv += riscv/sbi_pmu_test
diff --git a/tools/testing/selftests/kvm/s390/bear.c b/tools/testing/selftests/kvm/s390/bear.c
new file mode 100644
index 000000000000..fee4999532ae
--- /dev/null
+++ b/tools/testing/selftests/kvm/s390/bear.c
@@ -0,0 +1,184 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * LPSW(E|Y) bear tests.
+ * LPSW and LPSWE do set the bear but LPSWEY doesn't.
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+
+#include "test_util.h"
+#include "kvm_util.h"
+#include "kselftest.h"
+#include "ucall_common.h"
+#include "facility.h"
+
+static void guest_lpswey(void)
+{
+ extern void lpswey_dest_addr(void);
+ u64 psw[2] = {0x0400000180000000ULL, (uintptr_t)lpswey_dest_addr};
+ u64 bear;
+
+ asm volatile (
+ " larl %%r3,lpswey_addr\n"
+ "lpswey_addr:\n"
+ " .insn siy,0xeb0000000071,%[psw],0\n"
+ " nop\n"
+ " nop\n"
+ ".globl lpswey_dest_addr \n"
+ "lpswey_dest_addr:\n"
+ " .insn s,0xb2010000,%[bear]\n"
+ " lg %%r4, %[bear]\n"
+ " nop\n"
+ " nop\n"
+ : [bear] "=Q" (bear)
+ : [psw] "T" (psw)
+ : "cc", "r3", "r4"
+ );
+}
+
+static void guest_lpswe(void)
+{
+ extern void lpswe_dest_addr(void);
+ u64 psw[2] = {0x0400000180000000ULL, (uintptr_t)lpswe_dest_addr};
+ u64 bear;
+
+ asm volatile (
+ " larl %%r3,lpswe_addr\n"
+ "lpswe_addr:\n"
+ " lpswe %[psw]\n"
+ " nop\n"
+ " nop\n"
+ ".globl lpswe_dest_addr\n"
+ "lpswe_dest_addr:\n"
+ " .insn s,0xb2010000,%[bear]\n"
+ " lg %%r4, %[bear]\n"
+ " nop\n"
+ " nop\n"
+ : [bear] "=Q" (bear)
+ : [psw] "Q" (psw)
+ : "cc", "r3", "r4"
+ );
+}
+
+static void guest_lpsw(void)
+{
+ extern void lpsw_dest_addr(void);
+ u64 psw_short = (0x0400000180000000ULL | BIT(63 - 12) |
+ (uintptr_t)lpsw_dest_addr);
+ u64 bear;
+
+ asm volatile (
+ " larl %%r3,lpsw_addr\n"
+ "lpsw_addr:\n"
+ " lpsw %[psw]\n"
+ " nop\n"
+ " nop\n"
+ ".globl lpsw_dest_addr\n"
+ "lpsw_dest_addr:\n"
+ " .insn s,0xb2010000,%[bear]\n"
+ " lg %%r4, %[bear]\n"
+ " nop\n"
+ " nop\n"
+ : [bear] "=Q" (bear)
+ : [psw] "Q" (psw_short)
+ : "cc", "r3", "r4"
+ );
+}
+
+/* A machine check forces KVM to emulate PSW loading */
+static void inject_mcheck(struct kvm_vcpu *vcpu)
+{
+ struct kvm_s390_irq irq = {};
+ int irqs;
+
+ irq.type = KVM_S390_MCHK;
+ /* External damage mcheck */
+ irq.u.mchk.cr14 = BIT(63 - 38);
+ irq.u.mchk.mcic = BIT(58);
+ irqs = __vcpu_ioctl(vcpu, KVM_S390_IRQ, &irq);
+ TEST_ASSERT(irqs >= 0, "Error injecting MCHECK errno %d", errno);
+}
+
+static void test_lpswey(void)
+{
+ struct kvm_vcpu *vcpu;
+ struct kvm_run *run;
+ struct kvm_vm *vm;
+
+ vm = vm_create_with_one_vcpu(&vcpu, guest_lpswey);
+ inject_mcheck(vcpu);
+ run = vcpu->run;
+ vcpu_run(vcpu);
+ ksft_test_result(run->s.regs.gprs[3] != run->s.regs.gprs[4],
+ "emulation: lpswey bear does not match\n");
+ kvm_vm_free(vm);
+
+ vm = vm_create_with_one_vcpu(&vcpu, guest_lpswey);
+ run = vcpu->run;
+ vcpu_run(vcpu);
+ ksft_test_result(run->s.regs.gprs[3] &&
+ run->s.regs.gprs[3] != run->s.regs.gprs[4],
+ "interpretation: lpswey bear does not match\n");
+ kvm_vm_free(vm);
+}
+
+static void test_lpswe(void)
+{
+ struct kvm_vcpu *vcpu;
+ struct kvm_run *run;
+ struct kvm_vm *vm;
+
+ vm = vm_create_with_one_vcpu(&vcpu, guest_lpswe);
+ inject_mcheck(vcpu);
+ run = vcpu->run;
+ vcpu_run(vcpu);
+ ksft_test_result(run->s.regs.gprs[3] == run->s.regs.gprs[4],
+ "emulation: lpswe bear matches\n");
+ kvm_vm_free(vm);
+
+ vm = vm_create_with_one_vcpu(&vcpu, guest_lpsw);
+ run = vcpu->run;
+ vcpu_run(vcpu);
+ ksft_test_result(run->s.regs.gprs[3] &&
+ run->s.regs.gprs[3] == run->s.regs.gprs[4],
+ "interpretation: lpswe bear matches\n");
+ kvm_vm_free(vm);
+}
+
+static void test_lpsw(void)
+{
+ struct kvm_vcpu *vcpu;
+ struct kvm_run *run;
+ struct kvm_vm *vm;
+
+ vm = vm_create_with_one_vcpu(&vcpu, guest_lpsw);
+ inject_mcheck(vcpu);
+ run = vcpu->run;
+ vcpu_run(vcpu);
+ ksft_test_result(run->s.regs.gprs[3] == run->s.regs.gprs[4],
+ "emulation: lpsw bear matches\n");
+ kvm_vm_free(vm);
+
+ vm = vm_create_with_one_vcpu(&vcpu, guest_lpsw);
+ run = vcpu->run;
+ vcpu_run(vcpu);
+ ksft_test_result(run->s.regs.gprs[3] &&
+ run->s.regs.gprs[3] == run->s.regs.gprs[4],
+ "interpretation: lpsw bear matches\n");
+ kvm_vm_free(vm);
+}
+
+int main(int argc, char *argv[])
+{
+ TEST_REQUIRE(test_facility(193));
+
+ ksft_print_header();
+ ksft_set_plan(6);
+ test_lpsw();
+ test_lpswe();
+ test_lpswey();
+ ksft_finished();
+}
--
2.51.0
next prev parent reply other threads:[~2026-03-23 15:36 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-23 15:35 [PATCH 0/2] KVM: s390: Fix lpsw/e breaking event handling Janosch Frank
2026-03-23 15:35 ` [PATCH 1/2] " Janosch Frank
2026-03-25 7:51 ` Christian Borntraeger
2026-03-25 12:00 ` Claudio Imbrenda
2026-03-23 15:35 ` Janosch Frank [this message]
2026-03-25 8:49 ` [PATCH 2/2] KVM: s390: selftests: Add load psw bear test Christian Borntraeger
2026-03-25 10:29 ` Christian Borntraeger
2026-03-25 13:15 ` Janosch Frank
2026-03-25 13:19 ` [PATCH v2] " Janosch Frank
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=20260323153637.3683-3-frankja@linux.ibm.com \
--to=frankja@linux.ibm.com \
--cc=borntraeger@linux.ibm.com \
--cc=imbrenda@linux.ibm.com \
--cc=kvm@vger.kernel.org \
--cc=linux-s390@vger.kernel.org \
/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