From: Claudio Imbrenda <imbrenda@linux.ibm.com>
To: Janis Schoetterl-Glausch <scgl@linux.ibm.com>
Cc: Thomas Huth <thuth@redhat.com>,
Janosch Frank <frankja@linux.ibm.com>,
David Hildenbrand <david@redhat.com>,
kvm@vger.kernel.org, linux-s390@vger.kernel.org
Subject: Re: [kvm-unit-tests PATCH v4 1/2] s390x: Add specification exception test
Date: Thu, 13 Jan 2022 08:56:48 +0100 [thread overview]
Message-ID: <20220113085648.7cf81084@p-imbrenda> (raw)
In-Reply-To: <20220111163901.1263736-2-scgl@linux.ibm.com>
On Tue, 11 Jan 2022 17:39:00 +0100
Janis Schoetterl-Glausch <scgl@linux.ibm.com> wrote:
> Generate specification exceptions and check that they occur.
>
> Signed-off-by: Janis Schoetterl-Glausch <scgl@linux.ibm.com>
> ---
> s390x/Makefile | 1 +
> s390x/spec_ex.c | 154 ++++++++++++++++++++++++++++++++++++++++++++
> s390x/unittests.cfg | 3 +
> 3 files changed, 158 insertions(+)
> create mode 100644 s390x/spec_ex.c
>
> diff --git a/s390x/Makefile b/s390x/Makefile
> index 1e567c1..5635c08 100644
> --- a/s390x/Makefile
> +++ b/s390x/Makefile
> @@ -25,6 +25,7 @@ tests += $(TEST_DIR)/uv-host.elf
> tests += $(TEST_DIR)/edat.elf
> tests += $(TEST_DIR)/mvpg-sie.elf
> tests += $(TEST_DIR)/spec_ex-sie.elf
> +tests += $(TEST_DIR)/spec_ex.elf
> tests += $(TEST_DIR)/firq.elf
>
> tests_binary = $(patsubst %.elf,%.bin,$(tests))
> diff --git a/s390x/spec_ex.c b/s390x/spec_ex.c
> new file mode 100644
> index 0000000..a9f9f31
> --- /dev/null
> +++ b/s390x/spec_ex.c
> @@ -0,0 +1,154 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright IBM Corp. 2021
> + *
> + * Specification exception test.
> + * Tests that specification exceptions occur when expected.
> + *
> + * Can be extended by adding triggers to spec_ex_triggers, see comments below.
> + */
> +#include <stdlib.h>
> +#include <libcflat.h>
> +#include <asm/interrupt.h>
> +
> +static struct lowcore *lc = (struct lowcore *) 0;
> +
> +static bool invalid_psw_expected;
> +static struct psw expected_psw;
> +static struct psw invalid_psw;
> +static struct psw fixup_psw;
> +
> +/* The standard program exception handler cannot deal with invalid old PSWs,
> + * especially not invalid instruction addresses, as in that case one cannot
> + * find the instruction following the faulting one from the old PSW.
> + * The PSW to return to is set by load_psw.
> + */
> +static void fixup_invalid_psw(void)
> +{
> + // signal occurrence of invalid psw fixup
> + invalid_psw_expected = false;
> + invalid_psw = lc->pgm_old_psw;
> + lc->pgm_old_psw = fixup_psw;
> +}
> +
> +/* Load possibly invalid psw, but setup fixup_psw before,
> + * so that *fixup_invalid_psw() can bring us back onto the right track.
is the * just a typo?
> + * Also acts as compiler barrier, -> none required in expect/check_invalid_psw
> + */
> +static void load_psw(struct psw psw)
> +{
> + uint64_t scratch;
> +
> + fixup_psw.mask = extract_psw_mask();
> + asm volatile ( "larl %[scratch],nop%=\n"
> + " stg %[scratch],%[addr]\n"
> + " lpswe %[psw]\n"
> + "nop%=: nop\n"
> + : [scratch] "=&r"(scratch),
> + [addr] "=&T"(fixup_psw.addr)
> + : [psw] "Q"(psw)
> + : "cc", "memory"
> + );
> +}
> +
> +static void expect_invalid_psw(struct psw psw)
> +{
> + expected_psw = psw;
> + invalid_psw_expected = true;
> +}
> +
> +static int check_invalid_psw(void)
> +{
> + // toggled to signal occurrence of invalid psw fixup
please use /* */ style of comments also for single line comments
> + if (!invalid_psw_expected) {
> + if (expected_psw.mask == invalid_psw.mask &&
> + expected_psw.addr == invalid_psw.addr)
> + return 0;
> + report_fail("Wrong invalid PSW");
> + } else {
> + report_fail("Expected exception due to invalid PSW");
> + }
> + return 1;
> +}
> +
> +static int psw_bit_12_is_1(void)
> +{
> + struct psw invalid = { .mask = 0x0008000000000000, .addr = 0x00000000deadbeee};
> +
> + expect_invalid_psw(invalid);
> + load_psw(expected_psw);
> + return check_invalid_psw();
> +}
> +
> +static int bad_alignment(void)
> +{
> + uint32_t words[5] __attribute__((aligned(16)));
> + uint32_t (*bad_aligned)[4] = (uint32_t (*)[4])&words[1];
> +
> + asm volatile ("lpq %%r6,%[bad]"
> + : : [bad] "T"(*bad_aligned)
> + : "%r6", "%r7"
> + );
> + return 0;
> +}
> +
> +static int not_even(void)
> +{
> + uint64_t quad[2] __attribute__((aligned(16))) = {0};
> +
> + asm volatile (".insn rxy,0xe3000000008f,%%r7,%[quad]" //lpq %%r7,%[quad]
> + : : [quad] "T"(quad)
> + : "%r7", "%r8"
> + );
> + return 0;
> +}
> +
> +/*
> + * Harness for specification exception testing.
> + * func only triggers exception, reporting is taken care of automatically.
> + */
> +struct spec_ex_trigger {
> + const char *name;
> + int (*func)(void);
> + void (*fixup)(void);
> +};
> +
> +/* List of all tests to execute */
> +static const struct spec_ex_trigger spec_ex_triggers[] = {
> + { "psw_bit_12_is_1", &psw_bit_12_is_1, &fixup_invalid_psw },
> + { "bad_alignment", &bad_alignment, NULL },
> + { "not_even", ¬_even, NULL },
> + { NULL, NULL, NULL },
> +};
> +
> +static void test_spec_ex(const struct spec_ex_trigger *trigger)
> +{
> + uint16_t expected_pgm = PGM_INT_CODE_SPECIFICATION;
> + uint16_t pgm;
> + int rc;
> +
> + expect_pgm_int();
> + register_pgm_cleanup_func(trigger->fixup);
> + rc = trigger->func();
> + register_pgm_cleanup_func(NULL);
> + if (rc)
> + return;
why do you exit early in case of failure? (moreover, your are not even
reporting the failure)
> + pgm = clear_pgm_int();
> + report(pgm == expected_pgm, "Program interrupt: expected(%d) == received(%d)",
> + expected_pgm, pgm);
> +}
> +
> +int main(int argc, char **argv)
> +{
> + unsigned int i;
> +
> + report_prefix_push("specification exception");
> + for (i = 0; spec_ex_triggers[i].name; i++) {
> + report_prefix_push(spec_ex_triggers[i].name);
> + test_spec_ex(&spec_ex_triggers[i]);
> + report_prefix_pop();
> + }
> + report_prefix_pop();
> +
> + return report_summary();
> +}
> diff --git a/s390x/unittests.cfg b/s390x/unittests.cfg
> index 054560c..26510cf 100644
> --- a/s390x/unittests.cfg
> +++ b/s390x/unittests.cfg
> @@ -113,6 +113,9 @@ file = mvpg-sie.elf
> [spec_ex-sie]
> file = spec_ex-sie.elf
>
> +[spec_ex]
> +file = spec_ex.elf
> +
> [firq-linear-cpu-ids]
> file = firq.elf
> timeout = 20
next prev parent reply other threads:[~2022-01-13 12:21 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-11 16:38 [kvm-unit-tests PATCH v4 0/2] Add specification exception tests Janis Schoetterl-Glausch
2022-01-11 16:39 ` [kvm-unit-tests PATCH v4 1/2] s390x: Add specification exception test Janis Schoetterl-Glausch
2022-01-13 7:56 ` Claudio Imbrenda [this message]
2022-01-13 12:36 ` Janis Schoetterl-Glausch
2022-01-11 16:39 ` [kvm-unit-tests PATCH v4 2/2] s390x: Test specification exceptions during transaction Janis Schoetterl-Glausch
2022-01-13 12:20 ` Claudio Imbrenda
2022-01-13 12:49 ` Janis Schoetterl-Glausch
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=20220113085648.7cf81084@p-imbrenda \
--to=imbrenda@linux.ibm.com \
--cc=david@redhat.com \
--cc=frankja@linux.ibm.com \
--cc=kvm@vger.kernel.org \
--cc=linux-s390@vger.kernel.org \
--cc=scgl@linux.ibm.com \
--cc=thuth@redhat.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.