From: Janis Schoetterl-Glausch <scgl@linux.vnet.ibm.com>
To: Claudio Imbrenda <imbrenda@linux.ibm.com>
Cc: Janis Schoetterl-Glausch <scgl@linux.ibm.com>,
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 v3 1/2] s390x: Add specification exception test
Date: Wed, 27 Oct 2021 12:00:16 +0200 [thread overview]
Message-ID: <7649d08e-bc5c-512d-fb70-c2b9b512fc42@linux.vnet.ibm.com> (raw)
In-Reply-To: <20211026154113.1a9ab666@p-imbrenda>
On 10/26/21 15:41, Claudio Imbrenda wrote:
> On Tue, 26 Oct 2021 14:00:31 +0200
> Janis Schoetterl-Glausch <scgl@linux.vnet.ibm.com> wrote:
>
> [...]
>
>> I don't think that would work, the compiler might inline the function,
>> duplicating the label.
>
> __attribute__((noinline))
>
> :)
+ a comment on why it's necessary and at that point I don't think it's worth it.
>
>> I suppose I could replace the stg with an assignment in C, not sure if that's nicer.
>>
>>>> + fixup_psw.mask = extract_psw_mask();
>>>
>>> then you could add this here:
>>> fixup_psw.addr = after_lpswe;
>>>
>>>> + asm volatile (
>>>> + " larl %[scratch],nop%=\n"
>>>> + " stg %[scratch],%[addr]\n"
>>> ^ those two lines are no longer needed ^
>>>> + " lpswe %[psw]\n"
>>>> + "nop%=: nop\n"
>>> ".global after_lpswe \n"
>>> "after_lpswe: nop"
>>>> + : [scratch] "=&r"(scratch),
>>>> + [addr] "=&T"(fixup_psw.addr)
>>>> + : [psw] "Q"(psw)
>>>> + : "cc", "memory"
>>>> + );
>>>> +}
>
> [...]
>
>> That's nicer indeed.
>>>
>>>> + asm volatile ("lpq %0,%2"
>>>> + : "=r"(r1), "=r"(r2)
>>>
>>> since you're ignoring the return value, can't you hardcode r6, and mark
>>> it (and r7) as clobbered? like:
>>> "lpq 6, %[bad]"
>>> : : [bad] "T"(words[1])
>>> : "%r6", "%r7"
>>>
>> Ok, btw. is there a reason bare register numbers seem to be more common
>> compared to %%rN ?
>
> I don't know, I guess laziness?
>
>>
>>>> + : "T"(*bad_aligned)
>>>> + );
>>>> +}
>>>> +
>>>> +static void not_even(void)
>>>> +{
>>>> + uint64_t quad[2];
>>>> +
>>>> + register uint64_t r1 asm("7");
>>>> + register uint64_t r2 asm("8");
>>>> + asm volatile (".insn rxy,0xe3000000008f,%0,%2" //lpq
>>>> %0,%2
>>>
>>> this is even uglier. I guess you had already tried this?
>>>
>> Yes, the assembler won't let you do that.
>
> yeah I thought so
>
>>
>>> "lpq 7, %[good]"
>>> : : [good] "T"(quad)
>>> : "%r7", "%r8"
>>>
>>> if that doesn't work, then the same but with .insn
>
> I guess you can still try this ^ ?
Ok.
>
>>>
>>>> + : "=r"(r1), "=r"(r2)
>>>> + : "T"(quad)
>>>> + );
>>>> +}
>>>> +
>>>> +struct spec_ex_trigger {
>>>> + const char *name;
>>>> + void (*func)(void);
>>>> + void (*fixup)(void);
>>>> +};
>>>> +
>>>> +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},
>>>> +};
>>>> +
>>>
>>> this is a lot of infrastructure for 3 tests... (or even for 5 tests,
>>> since you will add the transactions in the next patch)
>>
>> Is it? I think we'd want a test for a "normal" specification exception,
>> and one for an invalid PSW at least. Even for just those two, I don't
>> think it would be nice to duplicate the test_spec_ex harness.
>
> usually we do duplicate code for simple tests, so that reviewers have
> an easier time understanding what's going on, on the other hand..
>
>>>
>>> are you planning to significantly extend this test in the future?
>>
>> Not really, but I thought having it be easily extensible might be nice.
>
> ..fair enough
>
> this way it will be easier to extend this in the future, even though we
> don't have any immediate plans to do so
>
> maybe add some words in the patch description, and some comments, to
> explain what's going on, to make it easier for others to understand
> this code
Ok.
>
>>>
>>>> +struct args {
>>>> + uint64_t iterations;
>>>> +};
>>>> +
>>>> +static void test_spec_ex(struct args *args,
>>>> + const struct spec_ex_trigger *trigger)
>>>> +{
>>>> + uint16_t expected_pgm = PGM_INT_CODE_SPECIFICATION;
>>>> + uint16_t pgm;
>>>> + unsigned int i;
>>>> +
>>>> + for (i = 0; i < args->iterations; i++) {
>>>> + expect_pgm_int();
>>>> + register_pgm_cleanup_func(trigger->fixup);
>>>> + trigger->func();
>>>> + register_pgm_cleanup_func(NULL);
>>>> + pgm = clear_pgm_int();
>>>> + if (pgm != expected_pgm) {
>>>> + report_fail("Program interrupt: expected(%d)
>>>> == received(%d)",
>>>> + expected_pgm,
>>>> + pgm);
>>>> + return;
>>>> + }
>>>> + }
>>>> + report_pass("Program interrupt: always expected(%d) ==
>>>> received(%d)",
>>>> + expected_pgm,
>>>> + expected_pgm);
>>>> +}
>>>> +
>>>> +static struct args parse_args(int argc, char **argv)
>>>
>>> do we _really_ need commandline arguments?
>>>
>> No, but they can be useful.
>> The iterations argument can be used to check if interpretation happens.
>> The transaction arguments can be useful while developing a test case.
>>
>>> is it really so important to be able to control these parameters?
>>>
>>> can you find some values for the parameters so that the test works (as
>>> in, it actually tests what it's supposed to) and also so that the whole
>>> unit test ends in less than 30 seconds?
>>
>> I think the defaults are fine for that, no?
>
> ok so they are only for convenience in case things go wrong?
Yes, for when you want to poke at it manually for whatever reason.
>
>>>
>>>> +{
>>>> + struct args args = {
>>>> + .iterations = 1,
>>>> + };
>>>> + unsigned int i;
>>>> + long arg;
>>>> + bool no_arg;
>>>> + char *end;
>>>> +
>>>> + for (i = 1; i < argc; i++) {
>>>> + no_arg = true;
>>>> + if (i < argc - 1) {
>>>> + no_arg = *argv[i + 1] == '\0';
>>>> + arg = strtol(argv[i + 1], &end, 10);
>>>> + no_arg |= *end != '\0';
>>>> + no_arg |= arg < 0;
>>>> + }
>>>> +
>>>> + if (!strcmp("--iterations", argv[i])) {
>>>> + if (no_arg)
>>>> + report_abort("--iterations needs a
>>>> positive parameter");
>>>> + args.iterations = arg;
>>>> + ++i;
>>>> + } else {
>>>> + report_abort("Unsupported parameter '%s'",
>>>> + argv[i]);
>>>> + }
>>>> + }
>
> I wonder if we can factor out the parameter parsing
I don't think it's worth it. Only three arguments are handled the same.
Doing this might be worthwhile tho:
for (i = 1; i < argc; i++) {
no_arg = true;
if (i < argc - 1) {
no_arg = *argv[i + 1] == '\0';
arg = strtol(argv[i + 1], &end, 10);
no_arg |= *end != '\0';
no_arg |= arg < 0;
}
cmp = "--iterations";
argp = &args.iterations;
if (!strcmp(cmp, argv[i])) {
if (no_arg)
report_abort("%s needs a positive parameter", cmp);
*argp = arg;
++i;
continue;
}
cmp = "--max-retries";
argp = &args.max_retries;
if (!strcmp(cmp, argv[i])) {
if (no_arg)
report_abort("%s needs a positive parameter", cmp);
*argp = arg;
++i;
continue;
}
cmp = "--suppress-info";
argp = &args.suppress_info;
if (!strcmp(cmp, argv[i])) {
if (no_arg)
report_abort("%s needs a positive parameter", cmp);
*argp = arg;
++i;
continue;
}
cmp = "--max-failures";
argp = &args.max_failures;
if (!strcmp(cmp, argv[i])) {
max_failures = true;
if (no_arg)
report_abort("%s needs a positive parameter", cmp);
*argp = arg;
++i;
continue;
}
if (!strcmp("--diagnose", argv[i])) {
args.diagnose = true;
continue;
}
if (!strcmp("--no-diagnose", argv[i])) {
args.diagnose = false;
continue;
}
report_abort("Unsupported parameter '%s'",
argv[i]);
}
>
>>>> + return args;
>>>> +}
>>>> +
>>>> +int main(int argc, char **argv)
>>>> +{
>>>> + unsigned int i;
>>>> +
>>>> + struct args args = parse_args(argc, argv);
>>>> +
>>>> + 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(&args, &spec_ex_triggers[i]);
>>>> + report_prefix_pop();
>>>> + }
>>>> + report_prefix_pop();
>>>> +
>>>> + return report_summary();
>>>> +}
>>>> diff --git a/s390x/unittests.cfg b/s390x/unittests.cfg
>>>> index 9e1802f..5f43d52 100644
>>>> --- a/s390x/unittests.cfg
>>>> +++ b/s390x/unittests.cfg
>>>> @@ -109,3 +109,6 @@ file = edat.elf
>>>>
>>>> [mvpg-sie]
>>>> file = mvpg-sie.elf
>>>> +
>>>> +[spec_ex]
>>>> +file = spec_ex.elf
>>>
>>
>
next prev parent reply other threads:[~2021-10-27 10:00 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-10-22 12:01 [kvm-unit-tests PATCH v3 0/2] Add specification exception tests Janis Schoetterl-Glausch
2021-10-22 12:01 ` [kvm-unit-tests PATCH v3 1/2] s390x: Add specification exception test Janis Schoetterl-Glausch
2021-10-25 17:17 ` Claudio Imbrenda
2021-10-26 12:00 ` Janis Schoetterl-Glausch
2021-10-26 13:41 ` Claudio Imbrenda
2021-10-27 10:00 ` Janis Schoetterl-Glausch [this message]
2021-10-27 12:08 ` Thomas Huth
2021-10-22 12:01 ` [kvm-unit-tests PATCH v3 2/2] s390x: Test specification exceptions during transaction Janis Schoetterl-Glausch
2021-10-25 17:30 ` Claudio Imbrenda
2021-10-25 18:28 ` Christian Borntraeger
2021-10-26 14:22 ` Janis Schoetterl-Glausch
2021-10-26 14:55 ` Claudio Imbrenda
2021-10-27 10:05 ` 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=7649d08e-bc5c-512d-fb70-c2b9b512fc42@linux.vnet.ibm.com \
--to=scgl@linux.vnet.ibm.com \
--cc=david@redhat.com \
--cc=frankja@linux.ibm.com \
--cc=imbrenda@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).