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

kdb_bp.c (11707B)


      1/*
      2 * Kernel Debugger Architecture Independent Breakpoint Handler
      3 *
      4 * This file is subject to the terms and conditions of the GNU General Public
      5 * License.  See the file "COPYING" in the main directory of this archive
      6 * for more details.
      7 *
      8 * Copyright (c) 1999-2004 Silicon Graphics, Inc.  All Rights Reserved.
      9 * Copyright (c) 2009 Wind River Systems, Inc.  All Rights Reserved.
     10 */
     11
     12#include <linux/string.h>
     13#include <linux/kernel.h>
     14#include <linux/init.h>
     15#include <linux/kdb.h>
     16#include <linux/kgdb.h>
     17#include <linux/smp.h>
     18#include <linux/sched.h>
     19#include <linux/interrupt.h>
     20#include "kdb_private.h"
     21
     22/*
     23 * Table of kdb_breakpoints
     24 */
     25kdb_bp_t kdb_breakpoints[KDB_MAXBPT];
     26
     27static void kdb_setsinglestep(struct pt_regs *regs)
     28{
     29	KDB_STATE_SET(DOING_SS);
     30}
     31
     32static char *kdb_rwtypes[] = {
     33	"Instruction(i)",
     34	"Instruction(Register)",
     35	"Data Write",
     36	"I/O",
     37	"Data Access"
     38};
     39
     40static char *kdb_bptype(kdb_bp_t *bp)
     41{
     42	if (bp->bp_type < 0 || bp->bp_type > 4)
     43		return "";
     44
     45	return kdb_rwtypes[bp->bp_type];
     46}
     47
     48static int kdb_parsebp(int argc, const char **argv, int *nextargp, kdb_bp_t *bp)
     49{
     50	int nextarg = *nextargp;
     51	int diag;
     52
     53	bp->bph_length = 1;
     54	if ((argc + 1) != nextarg) {
     55		if (strncasecmp(argv[nextarg], "datar", sizeof("datar")) == 0)
     56			bp->bp_type = BP_ACCESS_WATCHPOINT;
     57		else if (strncasecmp(argv[nextarg], "dataw", sizeof("dataw")) == 0)
     58			bp->bp_type = BP_WRITE_WATCHPOINT;
     59		else if (strncasecmp(argv[nextarg], "inst", sizeof("inst")) == 0)
     60			bp->bp_type = BP_HARDWARE_BREAKPOINT;
     61		else
     62			return KDB_ARGCOUNT;
     63
     64		bp->bph_length = 1;
     65
     66		nextarg++;
     67
     68		if ((argc + 1) != nextarg) {
     69			unsigned long len;
     70
     71			diag = kdbgetularg((char *)argv[nextarg],
     72					   &len);
     73			if (diag)
     74				return diag;
     75
     76
     77			if (len > 8)
     78				return KDB_BADLENGTH;
     79
     80			bp->bph_length = len;
     81			nextarg++;
     82		}
     83
     84		if ((argc + 1) != nextarg)
     85			return KDB_ARGCOUNT;
     86	}
     87
     88	*nextargp = nextarg;
     89	return 0;
     90}
     91
     92static int _kdb_bp_remove(kdb_bp_t *bp)
     93{
     94	int ret = 1;
     95	if (!bp->bp_installed)
     96		return ret;
     97	if (!bp->bp_type)
     98		ret = dbg_remove_sw_break(bp->bp_addr);
     99	else
    100		ret = arch_kgdb_ops.remove_hw_breakpoint(bp->bp_addr,
    101			 bp->bph_length,
    102			 bp->bp_type);
    103	if (ret == 0)
    104		bp->bp_installed = 0;
    105	return ret;
    106}
    107
    108static void kdb_handle_bp(struct pt_regs *regs, kdb_bp_t *bp)
    109{
    110	if (KDB_DEBUG(BP))
    111		kdb_printf("regs->ip = 0x%lx\n", instruction_pointer(regs));
    112
    113	/*
    114	 * Setup single step
    115	 */
    116	kdb_setsinglestep(regs);
    117
    118	/*
    119	 * Reset delay attribute
    120	 */
    121	bp->bp_delay = 0;
    122	bp->bp_delayed = 1;
    123}
    124
    125static int _kdb_bp_install(struct pt_regs *regs, kdb_bp_t *bp)
    126{
    127	int ret;
    128	/*
    129	 * Install the breakpoint, if it is not already installed.
    130	 */
    131
    132	if (KDB_DEBUG(BP))
    133		kdb_printf("%s: bp_installed %d\n",
    134			   __func__, bp->bp_installed);
    135	if (!KDB_STATE(SSBPT))
    136		bp->bp_delay = 0;
    137	if (bp->bp_installed)
    138		return 1;
    139	if (bp->bp_delay || (bp->bp_delayed && KDB_STATE(DOING_SS))) {
    140		if (KDB_DEBUG(BP))
    141			kdb_printf("%s: delayed bp\n", __func__);
    142		kdb_handle_bp(regs, bp);
    143		return 0;
    144	}
    145	if (!bp->bp_type)
    146		ret = dbg_set_sw_break(bp->bp_addr);
    147	else
    148		ret = arch_kgdb_ops.set_hw_breakpoint(bp->bp_addr,
    149			 bp->bph_length,
    150			 bp->bp_type);
    151	if (ret == 0) {
    152		bp->bp_installed = 1;
    153	} else {
    154		kdb_printf("%s: failed to set breakpoint at 0x%lx\n",
    155			   __func__, bp->bp_addr);
    156		if (!bp->bp_type) {
    157			kdb_printf("Software breakpoints are unavailable.\n"
    158				   "  Boot the kernel with rodata=off\n"
    159				   "  OR use hw breaks: help bph\n");
    160		}
    161		return 1;
    162	}
    163	return 0;
    164}
    165
    166/*
    167 * kdb_bp_install
    168 *
    169 *	Install kdb_breakpoints prior to returning from the
    170 *	kernel debugger.  This allows the kdb_breakpoints to be set
    171 *	upon functions that are used internally by kdb, such as
    172 *	printk().  This function is only called once per kdb session.
    173 */
    174void kdb_bp_install(struct pt_regs *regs)
    175{
    176	int i;
    177
    178	for (i = 0; i < KDB_MAXBPT; i++) {
    179		kdb_bp_t *bp = &kdb_breakpoints[i];
    180
    181		if (KDB_DEBUG(BP)) {
    182			kdb_printf("%s: bp %d bp_enabled %d\n",
    183				   __func__, i, bp->bp_enabled);
    184		}
    185		if (bp->bp_enabled)
    186			_kdb_bp_install(regs, bp);
    187	}
    188}
    189
    190/*
    191 * kdb_bp_remove
    192 *
    193 *	Remove kdb_breakpoints upon entry to the kernel debugger.
    194 *
    195 * Parameters:
    196 *	None.
    197 * Outputs:
    198 *	None.
    199 * Returns:
    200 *	None.
    201 * Locking:
    202 *	None.
    203 * Remarks:
    204 */
    205void kdb_bp_remove(void)
    206{
    207	int i;
    208
    209	for (i = KDB_MAXBPT - 1; i >= 0; i--) {
    210		kdb_bp_t *bp = &kdb_breakpoints[i];
    211
    212		if (KDB_DEBUG(BP)) {
    213			kdb_printf("%s: bp %d bp_enabled %d\n",
    214				   __func__, i, bp->bp_enabled);
    215		}
    216		if (bp->bp_enabled)
    217			_kdb_bp_remove(bp);
    218	}
    219}
    220
    221
    222/*
    223 * kdb_printbp
    224 *
    225 *	Internal function to format and print a breakpoint entry.
    226 *
    227 * Parameters:
    228 *	None.
    229 * Outputs:
    230 *	None.
    231 * Returns:
    232 *	None.
    233 * Locking:
    234 *	None.
    235 * Remarks:
    236 */
    237
    238static void kdb_printbp(kdb_bp_t *bp, int i)
    239{
    240	kdb_printf("%s ", kdb_bptype(bp));
    241	kdb_printf("BP #%d at ", i);
    242	kdb_symbol_print(bp->bp_addr, NULL, KDB_SP_DEFAULT);
    243
    244	if (bp->bp_enabled)
    245		kdb_printf("\n    is enabled ");
    246	else
    247		kdb_printf("\n    is disabled");
    248
    249	kdb_printf("  addr at %016lx, hardtype=%d installed=%d\n",
    250		   bp->bp_addr, bp->bp_type, bp->bp_installed);
    251
    252	kdb_printf("\n");
    253}
    254
    255/*
    256 * kdb_bp
    257 *
    258 *	Handle the bp commands.
    259 *
    260 *	[bp|bph] <addr-expression> [DATAR|DATAW]
    261 *
    262 * Parameters:
    263 *	argc	Count of arguments in argv
    264 *	argv	Space delimited command line arguments
    265 * Outputs:
    266 *	None.
    267 * Returns:
    268 *	Zero for success, a kdb diagnostic if failure.
    269 * Locking:
    270 *	None.
    271 * Remarks:
    272 *
    273 *	bp	Set breakpoint on all cpus.  Only use hardware assist if need.
    274 *	bph	Set breakpoint on all cpus.  Force hardware register
    275 */
    276
    277static int kdb_bp(int argc, const char **argv)
    278{
    279	int i, bpno;
    280	kdb_bp_t *bp, *bp_check;
    281	int diag;
    282	char *symname = NULL;
    283	long offset = 0ul;
    284	int nextarg;
    285	kdb_bp_t template = {0};
    286
    287	if (argc == 0) {
    288		/*
    289		 * Display breakpoint table
    290		 */
    291		for (bpno = 0, bp = kdb_breakpoints; bpno < KDB_MAXBPT;
    292		     bpno++, bp++) {
    293			if (bp->bp_free)
    294				continue;
    295			kdb_printbp(bp, bpno);
    296		}
    297
    298		return 0;
    299	}
    300
    301	nextarg = 1;
    302	diag = kdbgetaddrarg(argc, argv, &nextarg, &template.bp_addr,
    303			     &offset, &symname);
    304	if (diag)
    305		return diag;
    306	if (!template.bp_addr)
    307		return KDB_BADINT;
    308
    309	/*
    310	 * This check is redundant (since the breakpoint machinery should
    311	 * be doing the same check during kdb_bp_install) but gives the
    312	 * user immediate feedback.
    313	 */
    314	diag = kgdb_validate_break_address(template.bp_addr);
    315	if (diag)
    316		return diag;
    317
    318	/*
    319	 * Find an empty bp structure to allocate
    320	 */
    321	for (bpno = 0, bp = kdb_breakpoints; bpno < KDB_MAXBPT; bpno++, bp++) {
    322		if (bp->bp_free)
    323			break;
    324	}
    325
    326	if (bpno == KDB_MAXBPT)
    327		return KDB_TOOMANYBPT;
    328
    329	if (strcmp(argv[0], "bph") == 0) {
    330		template.bp_type = BP_HARDWARE_BREAKPOINT;
    331		diag = kdb_parsebp(argc, argv, &nextarg, &template);
    332		if (diag)
    333			return diag;
    334	} else {
    335		template.bp_type = BP_BREAKPOINT;
    336	}
    337
    338	/*
    339	 * Check for clashing breakpoints.
    340	 *
    341	 * Note, in this design we can't have hardware breakpoints
    342	 * enabled for both read and write on the same address.
    343	 */
    344	for (i = 0, bp_check = kdb_breakpoints; i < KDB_MAXBPT;
    345	     i++, bp_check++) {
    346		if (!bp_check->bp_free &&
    347		    bp_check->bp_addr == template.bp_addr) {
    348			kdb_printf("You already have a breakpoint at "
    349				   kdb_bfd_vma_fmt0 "\n", template.bp_addr);
    350			return KDB_DUPBPT;
    351		}
    352	}
    353
    354	template.bp_enabled = 1;
    355
    356	/*
    357	 * Actually allocate the breakpoint found earlier
    358	 */
    359	*bp = template;
    360	bp->bp_free = 0;
    361
    362	kdb_printbp(bp, bpno);
    363
    364	return 0;
    365}
    366
    367/*
    368 * kdb_bc
    369 *
    370 *	Handles the 'bc', 'be', and 'bd' commands
    371 *
    372 *	[bd|bc|be] <breakpoint-number>
    373 *	[bd|bc|be] *
    374 *
    375 * Parameters:
    376 *	argc	Count of arguments in argv
    377 *	argv	Space delimited command line arguments
    378 * Outputs:
    379 *	None.
    380 * Returns:
    381 *	Zero for success, a kdb diagnostic for failure
    382 * Locking:
    383 *	None.
    384 * Remarks:
    385 */
    386static int kdb_bc(int argc, const char **argv)
    387{
    388	unsigned long addr;
    389	kdb_bp_t *bp = NULL;
    390	int lowbp = KDB_MAXBPT;
    391	int highbp = 0;
    392	int done = 0;
    393	int i;
    394	int diag = 0;
    395
    396	int cmd;			/* KDBCMD_B? */
    397#define KDBCMD_BC	0
    398#define KDBCMD_BE	1
    399#define KDBCMD_BD	2
    400
    401	if (strcmp(argv[0], "be") == 0)
    402		cmd = KDBCMD_BE;
    403	else if (strcmp(argv[0], "bd") == 0)
    404		cmd = KDBCMD_BD;
    405	else
    406		cmd = KDBCMD_BC;
    407
    408	if (argc != 1)
    409		return KDB_ARGCOUNT;
    410
    411	if (strcmp(argv[1], "*") == 0) {
    412		lowbp = 0;
    413		highbp = KDB_MAXBPT;
    414	} else {
    415		diag = kdbgetularg(argv[1], &addr);
    416		if (diag)
    417			return diag;
    418
    419		/*
    420		 * For addresses less than the maximum breakpoint number,
    421		 * assume that the breakpoint number is desired.
    422		 */
    423		if (addr < KDB_MAXBPT) {
    424			lowbp = highbp = addr;
    425			highbp++;
    426		} else {
    427			for (i = 0, bp = kdb_breakpoints; i < KDB_MAXBPT;
    428			    i++, bp++) {
    429				if (bp->bp_addr == addr) {
    430					lowbp = highbp = i;
    431					highbp++;
    432					break;
    433				}
    434			}
    435		}
    436	}
    437
    438	/*
    439	 * Now operate on the set of breakpoints matching the input
    440	 * criteria (either '*' for all, or an individual breakpoint).
    441	 */
    442	for (bp = &kdb_breakpoints[lowbp], i = lowbp;
    443	    i < highbp;
    444	    i++, bp++) {
    445		if (bp->bp_free)
    446			continue;
    447
    448		done++;
    449
    450		switch (cmd) {
    451		case KDBCMD_BC:
    452			bp->bp_enabled = 0;
    453
    454			kdb_printf("Breakpoint %d at "
    455				   kdb_bfd_vma_fmt " cleared\n",
    456				   i, bp->bp_addr);
    457
    458			bp->bp_addr = 0;
    459			bp->bp_free = 1;
    460
    461			break;
    462		case KDBCMD_BE:
    463			bp->bp_enabled = 1;
    464
    465			kdb_printf("Breakpoint %d at "
    466				   kdb_bfd_vma_fmt " enabled",
    467				   i, bp->bp_addr);
    468
    469			kdb_printf("\n");
    470			break;
    471		case KDBCMD_BD:
    472			if (!bp->bp_enabled)
    473				break;
    474
    475			bp->bp_enabled = 0;
    476
    477			kdb_printf("Breakpoint %d at "
    478				   kdb_bfd_vma_fmt " disabled\n",
    479				   i, bp->bp_addr);
    480
    481			break;
    482		}
    483		if (bp->bp_delay && (cmd == KDBCMD_BC || cmd == KDBCMD_BD)) {
    484			bp->bp_delay = 0;
    485			KDB_STATE_CLEAR(SSBPT);
    486		}
    487	}
    488
    489	return (!done) ? KDB_BPTNOTFOUND : 0;
    490}
    491
    492/*
    493 * kdb_ss
    494 *
    495 *	Process the 'ss' (Single Step) command.
    496 *
    497 *	ss
    498 *
    499 * Parameters:
    500 *	argc	Argument count
    501 *	argv	Argument vector
    502 * Outputs:
    503 *	None.
    504 * Returns:
    505 *	KDB_CMD_SS for success, a kdb error if failure.
    506 * Locking:
    507 *	None.
    508 * Remarks:
    509 *
    510 *	Set the arch specific option to trigger a debug trap after the next
    511 *	instruction.
    512 */
    513
    514static int kdb_ss(int argc, const char **argv)
    515{
    516	if (argc != 0)
    517		return KDB_ARGCOUNT;
    518	/*
    519	 * Set trace flag and go.
    520	 */
    521	KDB_STATE_SET(DOING_SS);
    522	return KDB_CMD_SS;
    523}
    524
    525static kdbtab_t bptab[] = {
    526	{	.name = "bp",
    527		.func = kdb_bp,
    528		.usage = "[<vaddr>]",
    529		.help = "Set/Display breakpoints",
    530		.flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS,
    531	},
    532	{	.name = "bl",
    533		.func = kdb_bp,
    534		.usage = "[<vaddr>]",
    535		.help = "Display breakpoints",
    536		.flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS,
    537	},
    538	{	.name = "bc",
    539		.func = kdb_bc,
    540		.usage = "<bpnum>",
    541		.help = "Clear Breakpoint",
    542		.flags = KDB_ENABLE_FLOW_CTRL,
    543	},
    544	{	.name = "be",
    545		.func = kdb_bc,
    546		.usage = "<bpnum>",
    547		.help = "Enable Breakpoint",
    548		.flags = KDB_ENABLE_FLOW_CTRL,
    549	},
    550	{	.name = "bd",
    551		.func = kdb_bc,
    552		.usage = "<bpnum>",
    553		.help = "Disable Breakpoint",
    554		.flags = KDB_ENABLE_FLOW_CTRL,
    555	},
    556	{	.name = "ss",
    557		.func = kdb_ss,
    558		.usage = "",
    559		.help = "Single Step",
    560		.minlen = 1,
    561		.flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS,
    562	},
    563};
    564
    565static kdbtab_t bphcmd = {
    566	.name = "bph",
    567	.func = kdb_bp,
    568	.usage = "[<vaddr>]",
    569	.help = "[datar [length]|dataw [length]]   Set hw brk",
    570	.flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS,
    571};
    572
    573/* Initialize the breakpoint table and register	breakpoint commands. */
    574
    575void __init kdb_initbptab(void)
    576{
    577	int i;
    578	kdb_bp_t *bp;
    579
    580	/*
    581	 * First time initialization.
    582	 */
    583	memset(&kdb_breakpoints, '\0', sizeof(kdb_breakpoints));
    584
    585	for (i = 0, bp = kdb_breakpoints; i < KDB_MAXBPT; i++, bp++)
    586		bp->bp_free = 1;
    587
    588	kdb_register_table(bptab, ARRAY_SIZE(bptab));
    589	if (arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT)
    590		kdb_register_table(&bphcmd, 1);
    591}