diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2020-02-05 16:47:23 +0100 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2020-02-05 16:47:23 +0100 |
commit | 5779d60cccfbd325a68837795c6884c6bf6d7e67 (patch) | |
tree | fdf16084ccfdb6a9a59edd358c6b4e1d1818f742 | |
parent | 24dff0b0bf59dbd6700960167596eaebd0ac5c7d (diff) | |
parent | 00e4483399bd57c9b49f8e79c9aacf0024193536 (diff) | |
download | kvm-unit-tests-5779d60cccfbd325a68837795c6884c6bf6d7e67.tar.gz |
Merge tag 's390x-2020-02-04' of https://gitlab.com/huth/kvm-unit-tests into HEAD
* s390x smp patches from Janosch
* Updates for the gitlab and Travis CI
-rw-r--r-- | .gitlab-ci.yml | 2 | ||||
-rw-r--r-- | .travis.yml | 3 | ||||
-rw-r--r-- | lib/s390x/interrupt.c | 20 | ||||
-rw-r--r-- | lib/s390x/io.c | 2 | ||||
-rw-r--r-- | lib/s390x/smp.c | 59 | ||||
-rw-r--r-- | s390x/cstart64.S | 2 | ||||
-rw-r--r-- | s390x/smp.c | 80 |
7 files changed, 102 insertions, 66 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index cf3264d..3093239 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -64,7 +64,7 @@ build-x86_64: - ./configure --arch=x86_64 - make -j2 - ACCEL=tcg ./run_tests.sh - ioapic-split ioapic smptest smptest3 vmexit_cpuid vmexit_mov_from_cr8 + smptest smptest3 vmexit_cpuid vmexit_mov_from_cr8 vmexit_mov_to_cr8 vmexit_inl_pmtimer vmexit_ipi vmexit_ipi_halt vmexit_ple_round_robin vmexit_tscdeadline vmexit_tscdeadline_immed eventinj msr port80 setjmp syscall tsc rmap_chain umip intel_iommu diff --git a/.travis.yml b/.travis.yml index 091d071..f0cfc82 100644 --- a/.travis.yml +++ b/.travis.yml @@ -119,5 +119,4 @@ before_script: script: - make -j3 - ACCEL="${ACCEL:-tcg}" ./run_tests.sh -v $TESTS | tee results.txt - - if grep -q FAIL results.txt ; then exit 1 ; fi - - if ! grep -q PASS results.txt ; then exit 1 ; fi + - grep -q PASS results.txt && ! grep -q FAIL results.txt diff --git a/lib/s390x/interrupt.c b/lib/s390x/interrupt.c index ccb376a..3a40cac 100644 --- a/lib/s390x/interrupt.c +++ b/lib/s390x/interrupt.c @@ -109,8 +109,8 @@ void handle_pgm_int(void) if (!pgm_int_expected) { /* Force sclp_busy to false, otherwise we will loop forever */ sclp_handle_ext(); - report_abort("Unexpected program interrupt: %d at %#lx, ilen %d\n", - lc->pgm_int_code, lc->pgm_old_psw.addr, + report_abort("Unexpected program interrupt: %d on cpu %d at %#lx, ilen %d\n", + lc->pgm_int_code, stap(), lc->pgm_old_psw.addr, lc->pgm_int_id); } @@ -122,8 +122,8 @@ void handle_ext_int(void) { if (!ext_int_expected && lc->ext_int_code != EXT_IRQ_SERVICE_SIG) { - report_abort("Unexpected external call interrupt (code %#x): at %#lx", - lc->ext_int_code, lc->ext_old_psw.addr); + report_abort("Unexpected external call interrupt (code %#x): on cpu %d at %#lx", + lc->ext_int_code, stap(), lc->ext_old_psw.addr); return; } @@ -140,18 +140,18 @@ void handle_ext_int(void) void handle_mcck_int(void) { - report_abort("Unexpected machine check interrupt: at %#lx", - lc->mcck_old_psw.addr); + report_abort("Unexpected machine check interrupt: on cpu %d at %#lx", + stap(), lc->mcck_old_psw.addr); } void handle_io_int(void) { - report_abort("Unexpected io interrupt: at %#lx", - lc->io_old_psw.addr); + report_abort("Unexpected io interrupt: on cpu %d at %#lx", + stap(), lc->io_old_psw.addr); } void handle_svc_int(void) { - report_abort("Unexpected supervisor call interrupt: at %#lx", - lc->svc_old_psw.addr); + report_abort("Unexpected supervisor call interrupt: on cpu %d at %#lx", + stap(), lc->svc_old_psw.addr); } diff --git a/lib/s390x/io.c b/lib/s390x/io.c index 32f09b5..e091c37 100644 --- a/lib/s390x/io.c +++ b/lib/s390x/io.c @@ -46,6 +46,6 @@ void exit(int code) smp_teardown(); printf("\nEXIT: STATUS=%d\n", ((code) << 1) | 1); while (1) { - sigp(0, SIGP_STOP, 0, NULL); + sigp(stap(), SIGP_STOP, 0, NULL); } } diff --git a/lib/s390x/smp.c b/lib/s390x/smp.c index f57f420..3f86243 100644 --- a/lib/s390x/smp.c +++ b/lib/s390x/smp.c @@ -104,35 +104,52 @@ int smp_cpu_stop_store_status(uint16_t addr) return rc; } +static int smp_cpu_restart_nolock(uint16_t addr, struct psw *psw) +{ + int rc; + struct cpu *cpu = smp_cpu_from_addr(addr); + + if (!cpu) + return -1; + if (psw) { + cpu->lowcore->restart_new_psw.mask = psw->mask; + cpu->lowcore->restart_new_psw.addr = psw->addr; + } + /* + * Stop the cpu, so we don't have a race between a running cpu + * and the restart in the test that checks if the cpu is + * running after the restart. + */ + smp_cpu_stop_nolock(addr, false); + rc = sigp(addr, SIGP_RESTART, 0, NULL); + if (rc) + return rc; + /* + * The order has been accepted, but the actual restart may not + * have been performed yet, so wait until the cpu is running. + */ + while (!smp_cpu_running(addr)) + mb(); + cpu->active = true; + return 0; +} + int smp_cpu_restart(uint16_t addr) { - int rc = -1; - struct cpu *cpu; + int rc; spin_lock(&lock); - cpu = smp_cpu_from_addr(addr); - if (cpu) { - rc = sigp(addr, SIGP_RESTART, 0, NULL); - cpu->active = true; - } + rc = smp_cpu_restart_nolock(addr, NULL); spin_unlock(&lock); return rc; } int smp_cpu_start(uint16_t addr, struct psw psw) { - int rc = -1; - struct cpu *cpu; - struct lowcore *lc; + int rc; spin_lock(&lock); - cpu = smp_cpu_from_addr(addr); - if (cpu) { - lc = cpu->lowcore; - lc->restart_new_psw.mask = psw.mask; - lc->restart_new_psw.addr = psw.addr; - rc = sigp(addr, SIGP_RESTART, 0, NULL); - } + rc = smp_cpu_restart_nolock(addr, &psw); spin_unlock(&lock); return rc; } @@ -192,10 +209,10 @@ int smp_cpu_setup(uint16_t addr, struct psw psw) lc->sw_int_crs[0] = 0x0000000000040000UL; /* Start processing */ - rc = sigp_retry(cpu->addr, SIGP_RESTART, 0, NULL); - if (!rc) - cpu->active = true; - + smp_cpu_restart_nolock(addr, NULL); + /* Wait until the cpu has finished setup and started the provided psw */ + while (lc->restart_new_psw.addr != psw.addr) + mb(); out: spin_unlock(&lock); return rc; diff --git a/s390x/cstart64.S b/s390x/cstart64.S index 86dd4c4..9af6bb3 100644 --- a/s390x/cstart64.S +++ b/s390x/cstart64.S @@ -159,6 +159,8 @@ smp_cpu_setup_state: xgr %r1, %r1 lmg %r0, %r15, GEN_LC_SW_INT_GRS lctlg %c0, %c0, GEN_LC_SW_INT_CRS + /* We should only go once through cpu setup and not for every restart */ + stg %r14, GEN_LC_RESTART_NEW_PSW + 8 br %r14 pgm_int: diff --git a/s390x/smp.c b/s390x/smp.c index ab7e46c..fa40753 100644 --- a/s390x/smp.c +++ b/s390x/smp.c @@ -22,6 +22,19 @@ static int testflag = 0; +static void wait_for_flag(void) +{ + while (!testflag) + mb(); +} + +static void set_flag(int val) +{ + mb(); + testflag = val; + mb(); +} + static void cpu_loop(void) { for (;;) {} @@ -29,21 +42,19 @@ static void cpu_loop(void) static void test_func(void) { - testflag = 1; - mb(); + set_flag(1); cpu_loop(); } static void test_start(void) { struct psw psw; - psw.mask = extract_psw_mask(); + psw.mask = extract_psw_mask(); psw.addr = (unsigned long)test_func; - smp_cpu_setup(1, psw); - while (!testflag) { - mb(); - } + set_flag(0); + smp_cpu_start(1, psw); + wait_for_flag(); report(1, "start"); } @@ -98,6 +109,7 @@ static void test_store_status(void) report(1, "status written"); free_pages(status, PAGE_SIZE * 2); report_prefix_pop(); + smp_cpu_stop(1); report_prefix_pop(); } @@ -112,27 +124,26 @@ static void ecall(void) mask = extract_psw_mask(); mask |= PSW_MASK_EXT; load_psw_mask(mask); - testflag = 1; + set_flag(1); while (lc->ext_int_code != 0x1202) { mb(); } - report(1, "ecall"); - testflag= 1; + report(1, "received"); + set_flag(1); } static void test_ecall(void) { struct psw psw; - psw.mask = extract_psw_mask(); + psw.mask = extract_psw_mask(); psw.addr = (unsigned long)ecall; report_prefix_push("ecall"); - testflag= 0; - smp_cpu_destroy(1); + set_flag(0); - smp_cpu_setup(1, psw); - while (!testflag) { mb(); } - testflag= 0; + smp_cpu_start(1, psw); + wait_for_flag(); + set_flag(0); sigp(1, SIGP_EXTERNAL_CALL, 0, NULL); - while(!testflag) {mb();} + wait_for_flag(); smp_cpu_stop(1); report_prefix_pop(); } @@ -147,27 +158,26 @@ static void emcall(void) mask = extract_psw_mask(); mask |= PSW_MASK_EXT; load_psw_mask(mask); - testflag= 1; + set_flag(1); while (lc->ext_int_code != 0x1201) { mb(); } - report(1, "ecall"); - testflag = 1; + report(1, "received"); + set_flag(1); } static void test_emcall(void) { struct psw psw; - psw.mask = extract_psw_mask(); + psw.mask = extract_psw_mask(); psw.addr = (unsigned long)emcall; report_prefix_push("emcall"); - testflag= 0; - smp_cpu_destroy(1); + set_flag(0); - smp_cpu_setup(1, psw); - while (!testflag) { mb(); } - testflag= 0; + smp_cpu_start(1, psw); + wait_for_flag(); + set_flag(0); sigp(1, SIGP_EMERGENCY_SIGNAL, 0, NULL); - while(!testflag) { mb(); } + wait_for_flag(); smp_cpu_stop(1); report_prefix_pop(); } @@ -177,11 +187,11 @@ static void test_reset_initial(void) struct cpu_status *status = alloc_pages(0); struct psw psw; - psw.mask = extract_psw_mask(); + psw.mask = extract_psw_mask(); psw.addr = (unsigned long)test_func; report_prefix_push("reset initial"); - smp_cpu_setup(1, psw); + smp_cpu_start(1, psw); sigp_retry(1, SIGP_INITIAL_CPU_RESET, 0, NULL); sigp(1, SIGP_STORE_STATUS_AT_ADDRESS, (uintptr_t)status, NULL); @@ -208,11 +218,11 @@ static void test_reset(void) { struct psw psw; - psw.mask = extract_psw_mask(); + psw.mask = extract_psw_mask(); psw.addr = (unsigned long)test_func; report_prefix_push("cpu reset"); - smp_cpu_setup(1, psw); + smp_cpu_start(1, psw); sigp_retry(1, SIGP_CPU_RESET, 0, NULL); report(smp_cpu_stopped(1), "cpu stopped"); @@ -221,6 +231,7 @@ static void test_reset(void) int main(void) { + struct psw psw; report_prefix_push("smp"); if (smp_query_num_cpus() == 1) { @@ -228,6 +239,12 @@ int main(void) goto done; } + /* Setting up the cpu to give it a stack and lowcore */ + psw.mask = extract_psw_mask(); + psw.addr = (unsigned long)cpu_loop; + smp_cpu_setup(1, psw); + smp_cpu_stop(1); + test_start(); test_stop(); test_stop_store_status(); @@ -236,6 +253,7 @@ int main(void) test_emcall(); test_reset(); test_reset_initial(); + smp_cpu_destroy(1); done: report_prefix_pop(); |