Commit 93c3a0ba authored by Balamuruhan S's avatar Balamuruhan S Committed by Michael Ellerman
Browse files

powerpc/test_emulate_step: Enhancement to test negative scenarios



add provision to declare test is a negative scenario, verify
whether emulation fails and avoid executing it.

Signed-off-by: default avatarBalamuruhan S <bala24@linux.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20200626095158.1031507-2-bala24@linux.ibm.com
parent 8b98afc1
Loading
Loading
Loading
Loading
+21 −9
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#define IGNORE_GPR(n)	(0x1UL << (n))
#define IGNORE_XER	(0x1UL << 32)
#define IGNORE_CCR	(0x1UL << 33)
#define NEGATIVE_TEST	(0x1UL << 63)

#define TEST_PLD(r, base, i, pr) \
	ppc_inst_prefix(PPC_PREFIX_8LS | __PPC_PRFX_R(pr) | IMM_H(i), \
@@ -1135,8 +1136,10 @@ static struct compute_test compute_tests[] = {
};

static int __init emulate_compute_instr(struct pt_regs *regs,
					struct ppc_inst instr)
					struct ppc_inst instr,
					bool negative)
{
	int analysed;
	extern s32 patch__exec_instr;
	struct instruction_op op;

@@ -1145,12 +1148,16 @@ static int __init emulate_compute_instr(struct pt_regs *regs,

	regs->nip = patch_site_addr(&patch__exec_instr);

	if (analyse_instr(&op, regs, instr) != 1 ||
	    GETTYPE(op.type) != COMPUTE) {
		pr_info("execution failed, instruction = %s\n", ppc_inst_as_str(instr));
	analysed = analyse_instr(&op, regs, instr);
	if (analysed != 1 || GETTYPE(op.type) != COMPUTE) {
		if (negative)
			return -EFAULT;
		pr_info("emulation failed, instruction = %s\n", ppc_inst_as_str(instr));
		return -EFAULT;
	}

	if (analysed == 1 && negative)
		pr_info("negative test failed, instruction = %s\n", ppc_inst_as_str(instr));
	if (!negative)
		emulate_update_regs(regs, &op);
	return 0;
}
@@ -1189,7 +1196,7 @@ static void __init run_tests_compute(void)
	struct pt_regs *regs, exp, got;
	unsigned int i, j, k;
	struct ppc_inst instr;
	bool ignore_gpr, ignore_xer, ignore_ccr, passed;
	bool ignore_gpr, ignore_xer, ignore_ccr, passed, rc, negative;

	for (i = 0; i < ARRAY_SIZE(compute_tests); i++) {
		test = &compute_tests[i];
@@ -1203,6 +1210,7 @@ static void __init run_tests_compute(void)
			instr = test->subtests[j].instr;
			flags = test->subtests[j].flags;
			regs = &test->subtests[j].regs;
			negative = flags & NEGATIVE_TEST;
			ignore_xer = flags & IGNORE_XER;
			ignore_ccr = flags & IGNORE_CCR;
			passed = true;
@@ -1217,8 +1225,12 @@ static void __init run_tests_compute(void)
			exp.msr = MSR_KERNEL;
			got.msr = MSR_KERNEL;

			if (emulate_compute_instr(&got, instr) ||
			    execute_compute_instr(&exp, instr)) {
			rc = emulate_compute_instr(&got, instr, negative) != 0;
			if (negative) {
				/* skip executing instruction */
				passed = rc;
				goto print;
			} else if (rc || execute_compute_instr(&exp, instr)) {
				passed = false;
				goto print;
			}