On 7/9/21 11:22 AM, Cornelia Huck wrote: > On Tue, Jul 06 2021, Janis Schoetterl-Glausch <scgl@xxxxxxxxxxxxx> wrote: > >> Generate specification exceptions and check that they occur. >> Also generate specification exceptions during a transaction, >> which results in another interruption code. >> With the iterations argument one can check if specification >> exception interpretation occurs, e.g. by using a high value and >> checking that the debugfs counters are substantially lower. >> The argument is also useful for estimating the performance benefit >> of interpretation. >> >> Signed-off-by: Janis Schoetterl-Glausch <scgl@xxxxxxxxxxxxx> >> --- >> s390x/Makefile | 1 + >> lib/s390x/asm/arch_def.h | 1 + >> s390x/spec_ex.c | 344 +++++++++++++++++++++++++++++++++++++++ >> s390x/unittests.cfg | 3 + >> 4 files changed, 349 insertions(+) >> create mode 100644 s390x/spec_ex.c > > (...) > >> +static void lpsw(uint64_t psw) > > Maybe call this load_psw(), as you do a bit more than a simple lpsw? [...] > The indentation looks a bit funny here. [...] > Here as well. Ok, will fix. > >> +} > > (...) > >> +#define report_info_if(cond, fmt, ...) \ >> + do { \ >> + if (cond) { \ >> + report_info(fmt, ##__VA_ARGS__);\ >> + } \ >> + } while (0) > > I'm wondering whether such a wrapper function could be generally useful. > I've found 9 occurrences with: find . -type f \( -name "*.c" -o -name "*.h" \) -exec awk '/if\s*\(.*/{i=2;f=$0} /report_info/ && i>0{print FILENAME, NR-1 ":" f;r=4} r>1{print FILENAME, NR ":" $0;r--} r==1{print "--";r=0} {i--}' '{}' \; ./lib/s390x/css_lib.c 177: if (cc) { ./lib/s390x/css_lib.c 178: report_info("stsch: updating sch %08x failed with cc=%d", ./lib/s390x/css_lib.c 179: schid, cc); ./lib/s390x/css_lib.c 180: return false; -- ./lib/s390x/css_lib.c 183: if (!(pmcw->flags & PMCW_ENABLE)) { ./lib/s390x/css_lib.c 184: report_info("stsch: sch %08x not enabled", schid); ./lib/s390x/css_lib.c 185: return false; ./lib/s390x/css_lib.c 186: } -- ./lib/s390x/css_lib.c 207: if (cc) { ./lib/s390x/css_lib.c 208: report_info("stsch: sch %08x failed with cc=%d", schid, cc); ./lib/s390x/css_lib.c 209: return cc; ./lib/s390x/css_lib.c 210: } -- ./lib/s390x/css_lib.c 213: if ((pmcw->flags & (PMCW_ISC_MASK | PMCW_ENABLE)) == flags) { ./lib/s390x/css_lib.c 214: report_info("stsch: sch %08x already enabled", schid); ./lib/s390x/css_lib.c 215: return 0; ./lib/s390x/css_lib.c 216: } -- ./lib/s390x/css_lib.c 269: if (cc) { ./lib/s390x/css_lib.c 270: report_info("stsch: sch %08x failed with cc=%d", schid, cc); ./lib/s390x/css_lib.c 271: return false; ./lib/s390x/css_lib.c 272: } -- ./lib/s390x/css_lib.c 305: if (cc) { ./lib/s390x/css_lib.c 306: report_info("stsch: updating sch %08x failed with cc=%d", ./lib/s390x/css_lib.c 307: schid, cc); ./lib/s390x/css_lib.c 308: return false; -- ./lib/s390x/css_lib.c 466: if (irb.scsw.sch_stat & ~SCSW_SCHS_IL) { ./lib/s390x/css_lib.c 467: report_info("Unexpected Subch. status %02x", irb.scsw.sch_stat); ./lib/s390x/css_lib.c 468: ret = -1; ./lib/s390x/css_lib.c 469: goto end; -- ./s390x/sclp.c 80: if (res) { ./s390x/sclp.c 81: report_info("SCLP not ready (command %#x, address %p, cc %d)", cmd, addr, res); ./s390x/sclp.c 82: return false; ./s390x/sclp.c 83: } -- ./s390x/sclp.c 86: if (!((1ULL << pgm) & exp_pgm)) { ./s390x/sclp.c 87: report_info("First failure at addr %p, buf_len %d, cmd %#x, pgm code %d", ./s390x/sclp.c 88: addr, buf_len, cmd, pgm); ./s390x/sclp.c 89: return false; -- ./s390x/sclp.c 92: if (exp_rc && exp_rc != h->response_code) { ./s390x/sclp.c 93: report_info("First failure at addr %p, buf_len %d, cmd %#x, resp code %#x", ./s390x/sclp.c 94: addr, buf_len, cmd, h->response_code); ./s390x/sclp.c 95: return false; -- ./s390x/css.c 105: if (ret < 0) { ./s390x/css.c 106: report_info("no valid residual count"); ./s390x/css.c 107: } else if (ret != 0) { ./s390x/css.c 108: len = sizeof(*senseid) - ret; -- ./s390x/css.c 112: } else if (ret && len) ./s390x/css.c 113: report_info("transferred a shorter length: %d", len); ./s390x/css.c 114: } ./s390x/css.c 115: -- ./s390x/css.c 153: if (css_test_general_feature(CSSC_EXTENDED_MEASUREMENT_BLOCK)) ./s390x/css.c 154: report_info("Extended measurement block available"); ./s390x/css.c 155: ./s390x/css.c 156: /* bits 59-63 of MB address must be 0 if MBU is defined */ -- ./arm/psci.c 119: } else if (cpu_on_ret[cpu] != PSCI_RET_ALREADY_ON) { ./arm/psci.c 120: report_info("unexpected cpu_on return value: caller=CPU%d, ret=%d", cpu, cpu_on_ret[cpu]); ./arm/psci.c 121: failed = true; ./arm/psci.c 122: } -- ./arm/psci.c 125: if (ret_success != 1) { ./arm/psci.c 126: report_info("got %d CPU_ON success", ret_success); ./arm/psci.c 127: failed = true; ./arm/psci.c 128: } -- ./arm/pmu.c 236: if (!supported && warn) ./arm/pmu.c 237: report_info("event 0x%x is not supported", n); ./arm/pmu.c 238: return supported; ./arm/pmu.c 239:} -- ./arm/cache.c 115: if (dcache_clean) ./arm/cache.c 116: report_info("dcache clean to PoU required"); ./arm/cache.c 117: if (icache_inval) ./arm/cache.c 117: if (icache_inval) ./arm/cache.c 118: report_info("icache invalidation to PoU required"); ./arm/cache.c 119: ./arm/cache.c 120: check_code_generation(dcache_clean, icache_inval); -- ./arm/pl031.c 193: if (!irq_triggered) { ./arm/pl031.c 194: report_info(" RTC RIS: %"PRIx32, readl(&pl031->ris)); ./arm/pl031.c 195: report_info(" RTC MIS: %"PRIx32, readl(&pl031->mis)); ./arm/pl031.c 196: report_info(" RTC IMSC: %"PRIx32, readl(&pl031->imsc)); -- ./arm/gic.c 84: if (i) ./arm/gic.c 85: report_info("interrupts took more than %d ms", i * 100); ./arm/gic.c 86: /* Wait for unexpected interrupts to fire */ ./arm/gic.c 87: mdelay(100); -- ./arm/gic.c 115: if (has_gicv2 && irq_sender[cpu] != sender) { ./arm/gic.c 116: report_info("cpu%d received IPI from wrong sender %d", ./arm/gic.c 117: cpu, irq_sender[cpu]); ./arm/gic.c 118: pass = false; -- ./arm/gic.c 121: if (irq_number[cpu] != irqnum) { ./arm/gic.c 122: report_info("cpu%d received wrong irq %d", ./arm/gic.c 123: cpu, irq_number[cpu]); ./arm/gic.c 124: pass = false; -- ./arm/gic.c 128: if (missing || extra || unexpected) { ./arm/gic.c 129: report_info("ACKS: missing=%d extra=%d unexpected=%d", ./arm/gic.c 130: missing, extra, unexpected); ./arm/gic.c 131: pass = false; -- ./arm/gic.c 142: if (spurious[cpu]) ./arm/gic.c 143: report_info("WARN: cpu%d got %d spurious interrupts", ./arm/gic.c 144: cpu, spurious[cpu]); ./arm/gic.c 145: } -- ./arm/gic.c 194: if (acked[i] != expected[i]) { ./arm/gic.c 195: report_info("expected %d LPIs on PE #%d, %d observed", ./arm/gic.c 196: expected[i], i, acked[i]); ./arm/gic.c 197: pass = false; -- ./arm/gic.c 421: if (!res) ./arm/gic.c 422: report_info("byte 1 of 0x%08"PRIx32" => 0x%02"PRIx32, pattern & mask, reg); ./arm/gic.c 423: ./arm/gic.c 424: pattern = REPLACE_BYTE(pattern, 2, 0x1f); -- ./arm/gic.c 429: if (!res) ./arm/gic.c 430: report_info("writing 0x%02"PRIx32" into bytes 2 => 0x%08"PRIx32, ./arm/gic.c 431: BYTE(pattern, 2), reg); ./arm/gic.c 432:} -- ./arm/gic.c 519: if (reg != (pattern & cpu_mask)) ./arm/gic.c 520: report_info("writing %08"PRIx32" reads back as %08"PRIx32, ./arm/gic.c 521: pattern & cpu_mask, reg); ./arm/gic.c 522: -- ./x86/vmx_tests.c 4733: if (!(ctrl_cpu_rev[0].clr & CPU_NMI_WINDOW)) { ./x86/vmx_tests.c 4734: report_info("NMI-window exiting is not supported, skipping..."); ./x86/vmx_tests.c 4735: goto done; ./x86/vmx_tests.c 4736: } -- ./x86/vmx_tests.c 4841: if (un_cache) { ./x86/vmx_tests.c 4842: report_info("EPT paging structure memory-type is Un-cacheable\n"); ./x86/vmx_tests.c 4843: ctrl = true; ./x86/vmx_tests.c 4844: } else { -- ./x86/vmx_tests.c 4848: if (wr_bk) { ./x86/vmx_tests.c 4849: report_info("EPT paging structure memory-type is Write-back\n"); ./x86/vmx_tests.c 4850: ctrl = true; ./x86/vmx_tests.c 4851: } else { -- ./x86/vmx_tests.c 4899: if (msr & EPT_CAP_AD_FLAG) { ./x86/vmx_tests.c 4900: report_info("Processor supports accessed and dirty flag"); ./x86/vmx_tests.c 4901: eptp &= ~EPTP_AD_FLAG; ./x86/vmx_tests.c 4902: test_eptp_ad_bit(eptp, true); --