On Mon, 2023-03-27 at 10:21 +0200, Nico Boehr wrote: > Since we now have the ability to run guests without MSO/MSL, add a test > to make sure this doesn't break. > > Signed-off-by: Nico Boehr <nrb@xxxxxxxxxxxxx> > --- > s390x/Makefile | 2 + > s390x/sie-dat.c | 121 +++++++++++++++++++++++++++++++++++++ > s390x/snippets/c/sie-dat.c | 58 ++++++++++++++++++ > s390x/unittests.cfg | 3 + > 4 files changed, 184 insertions(+) > create mode 100644 s390x/sie-dat.c > create mode 100644 s390x/snippets/c/sie-dat.c > Test looks good to me. Some comments below. [...] > diff --git a/s390x/sie-dat.c b/s390x/sie-dat.c > new file mode 100644 > index 000000000000..37e46386181c > --- /dev/null > +++ b/s390x/sie-dat.c > @@ -0,0 +1,121 @@ > [...] > + > +/* keep in sync with TOTAL_PAGE_COUNT in s390x/snippets/c/sie-dat.c */ > +#define GUEST_TOTAL_PAGE_COUNT 256 This (1M) is the maximum snippet size (see snippet_setup_guest), is this intentional? In that case the comment is inaccurate, since you'd want to sync it with the maximum snippet size. You also know the actual snippet size SNIPPET_LEN(c, sie_dat) so I don't see why you'd need a define at all. > + > +static void test_sie_dat(void) > +{ > [...] > + > + /* the guest will now write to an unmapped address and we check that this causes a segment translation */ I'd prefer "causes a segment translation exception" [...] > diff --git a/s390x/snippets/c/sie-dat.c b/s390x/snippets/c/sie-dat.c > new file mode 100644 > index 000000000000..c9f7af0f3a56 > --- /dev/null > +++ b/s390x/snippets/c/sie-dat.c > @@ -0,0 +1,58 @@ > +/* SPDX-License-Identifier: GPL-2.0-only */ > +/* > + * Snippet used by the sie-dat.c test to verify paging without MSO/MSL > + * > + * Copyright (c) 2023 IBM Corp > + * > + * Authors: > + * Nico Boehr <nrb@xxxxxxxxxxxxx> > + */ > +#include <stddef.h> > +#include <inttypes.h> > +#include <string.h> > +#include <asm-generic/page.h> > + > +/* keep in sync with GUEST_TEST_PAGE_COUNT in s390x/sie-dat.c */ > +#define TEST_PAGE_COUNT 10 > +static uint8_t test_page[TEST_PAGE_COUNT * PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE))); > + > +/* keep in sync with GUEST_TOTAL_PAGE_COUNT in s390x/sie-dat.c */ > +#define TOTAL_PAGE_COUNT 256 > + > +static inline void force_exit(void) > +{ > + asm volatile(" diag 0,0,0x44\n"); Pretty sure the compiler will generate a leading tab, so this will be doubly indented. > +} > + > +static inline void force_exit_value(uint64_t val) > +{ > + asm volatile( > + " diag %[val],0,0x9c\n" > + : : [val] "d"(val) > + ); > +} > + > +__attribute__((section(".text"))) int main(void) Why is the attribute necessary? I know all the snippets have it, but I don't see why it's necessary. @Janosch ? > +{ > + uint8_t *invalid_ptr; > + > + memset(test_page, 0, sizeof(test_page)); > + /* tell the host the page's physical address (we're running DAT off) */ > + force_exit_value((uint64_t)test_page); > + > + /* write some value to the page so the host can verify it */ > + for (size_t i = 0; i < TEST_PAGE_COUNT; i++) > + test_page[i * PAGE_SIZE] = 42 + i; > + > + /* indicate we've written all pages */ > + force_exit(); > + > + /* the first unmapped address */ > + invalid_ptr = (uint8_t *)(TOTAL_PAGE_COUNT * PAGE_SIZE); Why not just use an address high enough you know it will not be mapped? -1 should do just fine. > + *invalid_ptr = 42; > + > + /* indicate we've written the non-allowed page (should never get here) */ > + force_exit(); > + > + return 0; > +} > diff --git a/s390x/unittests.cfg b/s390x/unittests.cfg > index d97eb5e943c8..aab0e670f2d4 100644 > --- a/s390x/unittests.cfg > +++ b/s390x/unittests.cfg > @@ -215,3 +215,6 @@ file = migration-skey.elf > smp = 2 > groups = migration > extra_params = -append '--parallel' > + > +[sie-dat] > +file = sie-dat.elf