cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

test_emulate_step_exec_instr.S (3507B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2/*
      3 * Non-emulated single-stepping support (currently limited to basic integer
      4 * computations) used to validate the instruction emulation infrastructure.
      5 *
      6 * Copyright (C) 2019 IBM Corporation
      7 */
      8
      9#include <asm/asm-offsets.h>
     10#include <asm/ppc_asm.h>
     11#include <asm/code-patching-asm.h>
     12#include <linux/errno.h>
     13
     14/* int exec_instr(struct pt_regs *regs) */
     15_GLOBAL(exec_instr)
     16
     17	/*
     18	 * Stack frame layout (INT_FRAME_SIZE bytes)
     19	 *   In-memory pt_regs	(SP + STACK_FRAME_OVERHEAD)
     20	 *   Scratch space	(SP + 8)
     21	 *   Back chain		(SP + 0)
     22	 */
     23
     24	/*
     25	 * Allocate a new stack frame with enough space to hold the register
     26	 * states in an in-memory pt_regs and also create the back chain to
     27	 * the caller's stack frame.
     28	 */
     29	stdu	r1, -INT_FRAME_SIZE(r1)
     30
     31	/*
     32	 * Save non-volatile GPRs on stack. This includes TOC pointer (GPR2)
     33	 * and local variables (GPR14 to GPR31). The register for the pt_regs
     34	 * parameter (GPR3) is saved additionally to ensure that the resulting
     35	 * register state can still be saved even if GPR3 gets overwritten
     36	 * when loading the initial register state for the test instruction.
     37	 * The stack pointer (GPR1) and the thread pointer (GPR13) are not
     38	 * saved as these should not be modified anyway.
     39	 */
     40	SAVE_GPRS(2, 3, r1)
     41	SAVE_NVGPRS(r1)
     42
     43	/*
     44	 * Save LR on stack to ensure that the return address is available
     45	 * even if it gets overwritten by the test instruction.
     46	 */
     47	mflr	r0
     48	std	r0, _LINK(r1)
     49
     50	/*
     51	 * Save CR on stack. For simplicity, the entire register is saved
     52	 * even though only fields 2 to 4 are non-volatile.
     53	 */
     54	mfcr	r0
     55	std	r0, _CCR(r1)
     56
     57	/*
     58	 * Load register state for the test instruction without touching the
     59	 * critical non-volatile registers. The register state is passed as a
     60	 * pointer to a pt_regs instance.
     61	 */
     62	subi	r31, r3, GPR0
     63
     64	/* Load LR from pt_regs */
     65	ld	r0, _LINK(r31)
     66	mtlr	r0
     67
     68	/* Load CR from pt_regs */
     69	ld	r0, _CCR(r31)
     70	mtcr	r0
     71
     72	/* Load XER from pt_regs */
     73	ld	r0, _XER(r31)
     74	mtxer	r0
     75
     76	/* Load GPRs from pt_regs */
     77	REST_GPR(0, r31)
     78	REST_GPRS(2, 12, r31)
     79	REST_NVGPRS(r31)
     80
     81	/* Placeholder for the test instruction */
     82	.balign 64
     831:	nop
     84	nop
     85	patch_site 1b patch__exec_instr
     86
     87	/*
     88	 * Since GPR3 is overwritten, temporarily restore it back to its
     89	 * original state, i.e. the pointer to pt_regs, to ensure that the
     90	 * resulting register state can be saved. Before doing this, a copy
     91	 * of it is created in the scratch space which is used later on to
     92	 * save it to pt_regs.
     93	 */
     94	std	r3, 8(r1)
     95	REST_GPR(3, r1)
     96
     97	/* Save resulting GPR state to pt_regs */
     98	subi	r3, r3, GPR0
     99	SAVE_GPR(0, r3)
    100	SAVE_GPR(2, r3)
    101	SAVE_GPRS(4, 12, r3)
    102	SAVE_NVGPRS(r3)
    103
    104	/* Save resulting LR to pt_regs */
    105	mflr	r0
    106	std	r0, _LINK(r3)
    107
    108	/* Save resulting CR to pt_regs */
    109	mfcr	r0
    110	std	r0, _CCR(r3)
    111
    112	/* Save resulting XER to pt_regs */
    113	mfxer	r0
    114	std	r0, _XER(r3)
    115
    116	/* Restore resulting GPR3 from scratch space and save it to pt_regs */
    117	ld	r0, 8(r1)
    118	std	r0, GPR3(r3)
    119
    120	/* Set return value to denote execution success */
    121	li	r3, 0
    122
    123	/* Continue */
    124	b	3f
    125
    126	/* Set return value to denote execution failure */
    1272:	li	r3, -EFAULT
    128
    129	/* Restore the non-volatile GPRs from stack */
    1303:	REST_GPR(2, r1)
    131	REST_NVGPRS(r1)
    132
    133	/* Restore LR from stack to be able to return */
    134	ld	r0, _LINK(r1)
    135	mtlr	r0
    136
    137	/* Restore CR from stack */
    138	ld	r0, _CCR(r1)
    139	mtcr	r0
    140
    141	/* Tear down stack frame */
    142	addi	r1, r1, INT_FRAME_SIZE
    143
    144	/* Return */
    145	blr
    146
    147	/* Setup exception table */
    148	EX_TABLE(1b, 2b)
    149
    150_ASM_NOKPROBE_SYMBOL(exec_instr)