Re: [kvm-unit-tests PATCH 5/5] s390x: Add test for STFLE interpretive execution (format-0)

Nina Schoetterl-Glausch
2023-12-14T10:18:49Z

On Wed, 2023-12-13 at 18:31 +0100, Nina Schoetterl-Glausch wrote:
> On Wed, 2023-12-13 at 18:00 +0100, Claudio Imbrenda wrote:
> > On Wed, 13 Dec 2023 13:49:42 +0100
> > Nina Schoetterl-Glausch <nsg@linux.ibm.com> wrote:
> >
> > > The STFLE instruction indicates installed facilities.
> > > SIE can interpretively execute STFLE.
> > > Use a snippet guest executing STFLE to get the result of
> > > interpretive execution and check the result.
> > >
> > > Signed-off-by: Nina Schoetterl-Glausch <nsg@linux.ibm.com>
> >
> > [...]
> >
> > > static inline void setup_facilities(void)
> > > diff --git a/s390x/snippets/c/stfle.c b/s390x/snippets/c/stfle.c
> > > new file mode 100644
> > > index 00000000..eb024a6a
> > > --- /dev/null
> > > +++ b/s390x/snippets/c/stfle.c
> > > @@ -0,0 +1,26 @@
> > > +/* SPDX-License-Identifier: GPL-2.0-only */
> > > +/*
> > > + * Copyright IBM Corp. 2023
> > > + *
> > > + * Snippet used by the STLFE interpretive execution facilities test.
> > > + */
> > > +#include <libcflat.h>
> > > +#include <snippet-guest.h>
> > > +
> > > +int main(void)
> > > +{
> > > + const unsigned int max_fac_len = 8;
> >
> > why 8?
>
> 8 is a somewhat arbitrary, large number :)
> I suppose I could choose an even larger one, maybe even PAGE_SIZE/8.
> That would guarantee that max_fac_len >= stfle_size() (8 is enough for that today)
> It's not necessary for max_fac_len >= stfle_size(), but probably good for
> test coverage.
> >
> > > + uint64_t res[max_fac_len + 1];
> > > +
> > > + res[0] = max_fac_len - 1;
> > > + asm volatile ( "lg 0,%[len]\n"
> > > + " stfle %[fac]\n"
> > > + " stg 0,%[len]\n"
> > > + : [fac] "=QS"(*(uint64_t(*)[max_fac_len])&res[1]),
> > > + [len] "+RT"(res[0])
> > > + :
> > > + : "%r0", "cc"
> > > + );
> > > + force_exit_value((uint64_t)&res);
> > > + return 0;
> > > +}
> > > diff --git a/s390x/stfle-sie.c b/s390x/stfle-sie.c
> > > new file mode 100644
> > > index 00000000..574319ed
> > > --- /dev/null
> > > +++ b/s390x/stfle-sie.c
> > > @@ -0,0 +1,132 @@

[...]

> > > + vm.sblk->fac = (uint32_t)(uint64_t)fac;
> > > + res = run_guest();
> > > + report(res.len == stfle_size(), "stfle len correct");

You're right, disregard everything below.
>
> ^ should be
>
> + report(res.len == min(stfle_size(), 8), "stfle len correct");
>
> For the case that the guest buffer was shorter.
>
> > > + report(!memcmp(*fac, res.mem, res.len * sizeof(uint64_t)),
> > > + "Guest facility list as specified");
> >
> > it seems like you are comparing the full facility list (stfle_size
> > doublewords long) with the result of STFLE in the guest, but the guest
> > is limited to 8 double words?
>
> Their prefixes must be the same. res.len is the guest length, so max 8 right now.
> >
> > > + report_prefix_pop();
> > > +}