Path: blob/master/arch/powerpc/lib/test_emulate_step_exec_instr.S
26439 views
/* SPDX-License-Identifier: GPL-2.0 */1/*2* Non-emulated single-stepping support (currently limited to basic integer3* computations) used to validate the instruction emulation infrastructure.4*5* Copyright (C) 2019 IBM Corporation6*/78#include <asm/asm-offsets.h>9#include <asm/ppc_asm.h>10#include <asm/code-patching-asm.h>11#include <linux/errno.h>1213/* int exec_instr(struct pt_regs *regs) */14_GLOBAL(exec_instr)1516/*17* Stack frame layout (INT_FRAME_SIZE bytes)18* In-memory pt_regs (SP + STACK_INT_FRAME_REGS)19* Scratch space (SP + 8)20* Back chain (SP + 0)21*/2223/*24* Allocate a new stack frame with enough space to hold the register25* states in an in-memory pt_regs and also create the back chain to26* the caller's stack frame.27*/28stdu r1, -INT_FRAME_SIZE(r1)2930/*31* Save non-volatile GPRs on stack. This includes TOC pointer (GPR2)32* and local variables (GPR14 to GPR31). The register for the pt_regs33* parameter (GPR3) is saved additionally to ensure that the resulting34* register state can still be saved even if GPR3 gets overwritten35* when loading the initial register state for the test instruction.36* The stack pointer (GPR1) and the thread pointer (GPR13) are not37* saved as these should not be modified anyway.38*/39SAVE_GPRS(2, 3, r1)40SAVE_NVGPRS(r1)4142/*43* Save LR on stack to ensure that the return address is available44* even if it gets overwritten by the test instruction.45*/46mflr r047std r0, _LINK(r1)4849/*50* Save CR on stack. For simplicity, the entire register is saved51* even though only fields 2 to 4 are non-volatile.52*/53mfcr r054std r0, _CCR(r1)5556/*57* Load register state for the test instruction without touching the58* critical non-volatile registers. The register state is passed as a59* pointer to a pt_regs instance.60*/61subi r31, r3, GPR06263/* Load LR from pt_regs */64ld r0, _LINK(r31)65mtlr r06667/* Load CR from pt_regs */68ld r0, _CCR(r31)69mtcr r07071/* Load XER from pt_regs */72ld r0, _XER(r31)73mtxer r07475/* Load GPRs from pt_regs */76REST_GPR(0, r31)77REST_GPRS(2, 12, r31)78REST_NVGPRS(r31)7980/* Placeholder for the test instruction */81.balign 64821: nop83nop84patch_site 1b patch__exec_instr8586/*87* Since GPR3 is overwritten, temporarily restore it back to its88* original state, i.e. the pointer to pt_regs, to ensure that the89* resulting register state can be saved. Before doing this, a copy90* of it is created in the scratch space which is used later on to91* save it to pt_regs.92*/93std r3, 8(r1)94REST_GPR(3, r1)9596/* Save resulting GPR state to pt_regs */97subi r3, r3, GPR098SAVE_GPR(0, r3)99SAVE_GPR(2, r3)100SAVE_GPRS(4, 12, r3)101SAVE_NVGPRS(r3)102103/* Save resulting LR to pt_regs */104mflr r0105std r0, _LINK(r3)106107/* Save resulting CR to pt_regs */108mfcr r0109std r0, _CCR(r3)110111/* Save resulting XER to pt_regs */112mfxer r0113std r0, _XER(r3)114115/* Restore resulting GPR3 from scratch space and save it to pt_regs */116ld r0, 8(r1)117std r0, GPR3(r3)118119/* Set return value to denote execution success */120li r3, 0121122/* Continue */123b 3f124125/* Set return value to denote execution failure */1262: li r3, -EFAULT127128/* Restore the non-volatile GPRs from stack */1293: REST_GPR(2, r1)130REST_NVGPRS(r1)131132/* Restore LR from stack to be able to return */133ld r0, _LINK(r1)134mtlr r0135136/* Restore CR from stack */137ld r0, _CCR(r1)138mtcr r0139140/* Tear down stack frame */141addi r1, r1, INT_FRAME_SIZE142143/* Return */144blr145146/* Setup exception table */147EX_TABLE(1b, 2b)148149_ASM_NOKPROBE_SYMBOL(exec_instr)150151152