On 08.04.2016 14:14, Andrew Jones wrote: > On Fri, Apr 08, 2016 at 01:35:29PM +0200, Thomas Huth wrote: >> This test can be used to check whether the SPR (special purpose >> registers) of the PowerPC CPU are migrated right. It first fills >> the various SPRs with some non-zero value, then reads the values >> back into a first array, then waits for a key (with the '-w' option) >> so that it is possible to migrate the VM, and finally reads the >> values from the SPRs back into another array and then compares it >> with the initial values. >> Currently the test only supports the SPRs from the PowerISA v2.07 >> specification (i.e. POWER8 CPUs), but other versions should be >> pretty easy to add later. >> >> Signed-off-by: Thomas Huth <thuth@xxxxxxxxxx> >> --- >> powerpc/Makefile.common | 5 +- >> powerpc/sprs.c | 230 ++++++++++++++++++++++++++++++++++++++++++++++++ >> powerpc/unittests.cfg | 4 + >> 3 files changed, 238 insertions(+), 1 deletion(-) >> create mode 100644 powerpc/sprs.c [...] >> diff --git a/powerpc/sprs.c b/powerpc/sprs.c >> new file mode 100644 >> index 0000000..e99501f >> --- /dev/null >> +++ b/powerpc/sprs.c >> @@ -0,0 +1,230 @@ >> +/* >> + * Test SPRs >> + * >> + * Copyright 2016 Thomas Huth, Red Hat Inc. >> + * >> + * This work is licensed under the terms of the GNU LGPL, version 2. >> + * >> + * The basic idea of this test is to check whether the contents of the Special >> + * Purpose Registers (SPRs) are preserved correctly during migration. So we >> + * fill in the SPRs with a well-known value, read the values back (since not >> + * all bits might be retained in the SPRs), then wait for a key (if the '-w' >> + * option has been specified) so that the user has a chance to migrate the VM, >> + * and after a key has been pressed, we read back the values again and compare >> + * them with the values before the migration, reporting errors for mismatches. >> + * Note that we do not test all SPRs since some of the registers change their >> + * content automatically, and some are only accessible with hypervisor privi- >> + * leges, so we have to omit those registers. >> + */ >> +#include <libcflat.h> >> +#include <util.h> >> +#include <alloc.h> >> +#include <asm/hcall.h> >> + >> +#define mfspr(nr) ({ \ >> + uint64_t ret; \ >> + asm volatile("mfspr %0,%1" : "=r"(ret) : "i"(nr)); \ >> + ret; \ >> +}) >> + >> +#define mtspr(nr, val) \ >> + asm volatile("mtspr %0,%1" : : "i"(nr), "r"(val)); > > You may want these defines in processor.h to share with other tests. Ok, mfspr() is already used in spapr_hcall.c, too, so this is a good idea. >> + >> +uint64_t before[1024], after[1024]; >> + >> +static int h_get_term_char(uint64_t termno) >> +{ >> + register uint64_t r3 asm("r3") = 0x54; /* H_GET_TERM_CHAR */ >> + register uint64_t r4 asm("r4") = termno; >> + register uint64_t r5 asm("r5"); >> + >> + asm volatile (" sc 1 " : "+r"(r3), "+r"(r4), "=r"(r5) >> + : "r"(r3), "r"(r4)); >> + >> + return r3 == H_SUCCESS && r4 > 0 ? r5 >> 48 : 0; >> +} > > You may want this in hcall.h to share with other tests. Not sure whether it's of any use to another test, since they normally run automatically, without user interaction. It's just this test that needs to wait a little bit for the end of migration ... so I'd rather keep it here until we have another test that needs it. [...] >> +int main(int argc, char **argv) >> +{ >> + int i; >> + >> + if (argc > 1) >> + report_abort("Warning: Unsupported arguments!"); >> + >> + puts("Settings SPRs...\n"); >> + set_sprs(0xcafefacec0debabeULL); >> + >> + memset(before, 0, sizeof(before)); >> + memset(after, 0, sizeof(after)); > > before and after shouldn't need the memsets, as they're in the bss. Ok. >> + >> + get_sprs(before); >> + >> + if (argc > 0 && !strcmp(argv[0], "-w")) { >> + puts("Now migrate the VM, then press a key...\n"); >> + while (h_get_term_char(0) == 0) >> + ; >> + } else { >> + puts("Parameter '-w' not specified - not waiting for a key.\n"); >> + } >> + >> + get_sprs(after); >> + >> + puts("Checking SPRs...\n"); >> + for (i = 0; i < 1024; i++) { >> + if (before[i] != 0 || after[i] != 0) >> + report("SPR %d:\t0x%016lx <==> 0x%016lx", >> + before[i] == after[i], i, before[i], after[i]); >> + } >> + >> + return report_summary(); >> +} [...] > This is an interesting use of kvm-unit-tests. Ideally we'd keep avoid > the key press, which could complicate an automated test. Above you say > some SPRs change their content automatically. Are any of those changes > something that can be predicted in the case of a migration? I.e. could > we monitor them to see if a migration occurred? I don't think that it is very easy to detect the end of the migration like this... the registers I was talking about are things like the decrementer or timebase registers. If we really want to automate this, we could maybe use something like the machine check interrupt instead (which can be triggered with the "nmi" HMP command in QEMU, I think) to let the guest know about the end of the migration. But all that would also require quite some additional logic in the runner script, I think. Not sure whether it's worth the effort just for this one small test, which can also be run manually from time to time... But if you think we should really go this way, let me know, then I can have a try... Thomas -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html