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

kgdb.c (14910B)


      1/*
      2 * PowerPC backend to the KGDB stub.
      3 *
      4 * 1998 (c) Michael AK Tesch (tesch@cs.wisc.edu)
      5 * Copyright (C) 2003 Timesys Corporation.
      6 * Copyright (C) 2004-2006 MontaVista Software, Inc.
      7 * PPC64 Mods (C) 2005 Frank Rowand (frowand@mvista.com)
      8 * PPC32 support restored by Vitaly Wool <vwool@ru.mvista.com> and
      9 * Sergei Shtylyov <sshtylyov@ru.mvista.com>
     10 * Copyright (C) 2007-2008 Wind River Systems, Inc.
     11 *
     12 * This file is licensed under the terms of the GNU General Public License
     13 * version 2. This program as licensed "as is" without any warranty of any
     14 * kind, whether express or implied.
     15 */
     16
     17#include <linux/kernel.h>
     18#include <linux/kgdb.h>
     19#include <linux/smp.h>
     20#include <linux/signal.h>
     21#include <linux/ptrace.h>
     22#include <linux/kdebug.h>
     23#include <asm/current.h>
     24#include <asm/processor.h>
     25#include <asm/machdep.h>
     26#include <asm/debug.h>
     27#include <asm/code-patching.h>
     28#include <linux/slab.h>
     29#include <asm/inst.h>
     30
     31/*
     32 * This table contains the mapping between PowerPC hardware trap types, and
     33 * signals, which are primarily what GDB understands.  GDB and the kernel
     34 * don't always agree on values, so we use constants taken from gdb-6.2.
     35 */
     36static struct hard_trap_info
     37{
     38	unsigned int tt;		/* Trap type code for powerpc */
     39	unsigned char signo;		/* Signal that we map this trap into */
     40} hard_trap_info[] = {
     41	{ 0x0100, 0x02 /* SIGINT */  },		/* system reset */
     42	{ 0x0200, 0x0b /* SIGSEGV */ },		/* machine check */
     43	{ 0x0300, 0x0b /* SIGSEGV */ },		/* data access */
     44	{ 0x0400, 0x0b /* SIGSEGV */ },		/* instruction access */
     45	{ 0x0500, 0x02 /* SIGINT */  },		/* external interrupt */
     46	{ 0x0600, 0x0a /* SIGBUS */  },		/* alignment */
     47	{ 0x0700, 0x05 /* SIGTRAP */ },		/* program check */
     48	{ 0x0800, 0x08 /* SIGFPE */  },		/* fp unavailable */
     49	{ 0x0900, 0x0e /* SIGALRM */ },		/* decrementer */
     50	{ 0x0c00, 0x14 /* SIGCHLD */ },		/* system call */
     51#ifdef CONFIG_BOOKE_OR_40x
     52	{ 0x2002, 0x05 /* SIGTRAP */ },		/* debug */
     53#if defined(CONFIG_FSL_BOOKE)
     54	{ 0x2010, 0x08 /* SIGFPE */  },		/* spe unavailable */
     55	{ 0x2020, 0x08 /* SIGFPE */  },		/* spe unavailable */
     56	{ 0x2030, 0x08 /* SIGFPE */  },		/* spe fp data */
     57	{ 0x2040, 0x08 /* SIGFPE */  },		/* spe fp data */
     58	{ 0x2050, 0x08 /* SIGFPE */  },		/* spe fp round */
     59	{ 0x2060, 0x0e /* SIGILL */  },		/* performance monitor */
     60	{ 0x2900, 0x08 /* SIGFPE */  },		/* apu unavailable */
     61	{ 0x3100, 0x0e /* SIGALRM */ },		/* fixed interval timer */
     62	{ 0x3200, 0x02 /* SIGINT */  }, 	/* watchdog */
     63#else /* ! CONFIG_FSL_BOOKE */
     64	{ 0x1000, 0x0e /* SIGALRM */ },		/* prog interval timer */
     65	{ 0x1010, 0x0e /* SIGALRM */ },		/* fixed interval timer */
     66	{ 0x1020, 0x02 /* SIGINT */  }, 	/* watchdog */
     67	{ 0x2010, 0x08 /* SIGFPE */  },		/* fp unavailable */
     68	{ 0x2020, 0x08 /* SIGFPE */  },		/* ap unavailable */
     69#endif
     70#else /* !CONFIG_BOOKE_OR_40x */
     71	{ 0x0d00, 0x05 /* SIGTRAP */ },		/* single-step */
     72#if defined(CONFIG_PPC_8xx)
     73	{ 0x1000, 0x04 /* SIGILL */  },		/* software emulation */
     74#else /* ! CONFIG_PPC_8xx */
     75	{ 0x0f00, 0x04 /* SIGILL */  },		/* performance monitor */
     76	{ 0x0f20, 0x08 /* SIGFPE */  },		/* altivec unavailable */
     77	{ 0x1300, 0x05 /* SIGTRAP */ }, 	/* instruction address break */
     78#if defined(CONFIG_PPC64)
     79	{ 0x1200, 0x05 /* SIGILL */  },		/* system error */
     80	{ 0x1500, 0x04 /* SIGILL */  },		/* soft patch */
     81	{ 0x1600, 0x04 /* SIGILL */  },		/* maintenance */
     82	{ 0x1700, 0x08 /* SIGFPE */  },		/* altivec assist */
     83	{ 0x1800, 0x04 /* SIGILL */  },		/* thermal */
     84#else /* ! CONFIG_PPC64 */
     85	{ 0x1400, 0x02 /* SIGINT */  },		/* SMI */
     86	{ 0x1600, 0x08 /* SIGFPE */  },		/* altivec assist */
     87	{ 0x1700, 0x04 /* SIGILL */  },		/* TAU */
     88	{ 0x2000, 0x05 /* SIGTRAP */ },		/* run mode */
     89#endif
     90#endif
     91#endif
     92	{ 0x0000, 0x00 }			/* Must be last */
     93};
     94
     95static int computeSignal(unsigned int tt)
     96{
     97	struct hard_trap_info *ht;
     98
     99	for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
    100		if (ht->tt == tt)
    101			return ht->signo;
    102
    103	return SIGHUP;		/* default for things we don't know about */
    104}
    105
    106/**
    107 *
    108 *	kgdb_skipexception - Bail out of KGDB when we've been triggered.
    109 *	@exception: Exception vector number
    110 *	@regs: Current &struct pt_regs.
    111 *
    112 *	On some architectures we need to skip a breakpoint exception when
    113 *	it occurs after a breakpoint has been removed.
    114 *
    115 */
    116int kgdb_skipexception(int exception, struct pt_regs *regs)
    117{
    118	return kgdb_isremovedbreak(regs->nip);
    119}
    120
    121static int kgdb_debugger_ipi(struct pt_regs *regs)
    122{
    123	kgdb_nmicallback(raw_smp_processor_id(), regs);
    124	return 0;
    125}
    126
    127#ifdef CONFIG_SMP
    128void kgdb_roundup_cpus(void)
    129{
    130	smp_send_debugger_break();
    131}
    132#endif
    133
    134/* KGDB functions to use existing PowerPC64 hooks. */
    135static int kgdb_debugger(struct pt_regs *regs)
    136{
    137	return !kgdb_handle_exception(1, computeSignal(TRAP(regs)),
    138				      DIE_OOPS, regs);
    139}
    140
    141static int kgdb_handle_breakpoint(struct pt_regs *regs)
    142{
    143	if (user_mode(regs))
    144		return 0;
    145
    146	if (kgdb_handle_exception(1, SIGTRAP, 0, regs) != 0)
    147		return 0;
    148
    149	if (*(u32 *)regs->nip == BREAK_INSTR)
    150		regs_add_return_ip(regs, BREAK_INSTR_SIZE);
    151
    152	return 1;
    153}
    154
    155static int kgdb_singlestep(struct pt_regs *regs)
    156{
    157	if (user_mode(regs))
    158		return 0;
    159
    160	kgdb_handle_exception(0, SIGTRAP, 0, regs);
    161
    162	return 1;
    163}
    164
    165static int kgdb_iabr_match(struct pt_regs *regs)
    166{
    167	if (user_mode(regs))
    168		return 0;
    169
    170	if (kgdb_handle_exception(0, computeSignal(TRAP(regs)), 0, regs) != 0)
    171		return 0;
    172	return 1;
    173}
    174
    175static int kgdb_break_match(struct pt_regs *regs)
    176{
    177	if (user_mode(regs))
    178		return 0;
    179
    180	if (kgdb_handle_exception(0, computeSignal(TRAP(regs)), 0, regs) != 0)
    181		return 0;
    182	return 1;
    183}
    184
    185#define PACK64(ptr, src) do { *(ptr++) = (src); } while (0)
    186
    187#define PACK32(ptr, src) do {          \
    188	u32 *ptr32;                   \
    189	ptr32 = (u32 *)ptr;           \
    190	*(ptr32++) = (src);           \
    191	ptr = (unsigned long *)ptr32; \
    192	} while (0)
    193
    194void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
    195{
    196	struct pt_regs *regs = (struct pt_regs *)(p->thread.ksp +
    197						  STACK_FRAME_OVERHEAD);
    198	unsigned long *ptr = gdb_regs;
    199	int reg;
    200
    201	memset(gdb_regs, 0, NUMREGBYTES);
    202
    203	/* Regs GPR0-2 */
    204	for (reg = 0; reg < 3; reg++)
    205		PACK64(ptr, regs->gpr[reg]);
    206
    207	/* Regs GPR3-13 are caller saved, not in regs->gpr[] */
    208	ptr += 11;
    209
    210	/* Regs GPR14-31 */
    211	for (reg = 14; reg < 32; reg++)
    212		PACK64(ptr, regs->gpr[reg]);
    213
    214#ifdef CONFIG_FSL_BOOKE
    215#ifdef CONFIG_SPE
    216	for (reg = 0; reg < 32; reg++)
    217		PACK64(ptr, p->thread.evr[reg]);
    218#else
    219	ptr += 32;
    220#endif
    221#else
    222	/* fp registers not used by kernel, leave zero */
    223	ptr += 32 * 8 / sizeof(long);
    224#endif
    225
    226	PACK64(ptr, regs->nip);
    227	PACK64(ptr, regs->msr);
    228	PACK32(ptr, regs->ccr);
    229	PACK64(ptr, regs->link);
    230	PACK64(ptr, regs->ctr);
    231	PACK32(ptr, regs->xer);
    232
    233	BUG_ON((unsigned long)ptr >
    234	       (unsigned long)(((void *)gdb_regs) + NUMREGBYTES));
    235}
    236
    237#define GDB_SIZEOF_REG sizeof(unsigned long)
    238#define GDB_SIZEOF_REG_U32 sizeof(u32)
    239
    240#ifdef CONFIG_FSL_BOOKE
    241#define GDB_SIZEOF_FLOAT_REG sizeof(unsigned long)
    242#else
    243#define GDB_SIZEOF_FLOAT_REG sizeof(u64)
    244#endif
    245
    246struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] =
    247{
    248	{ "r0", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[0]) },
    249	{ "r1", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[1]) },
    250	{ "r2", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[2]) },
    251	{ "r3", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[3]) },
    252	{ "r4", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[4]) },
    253	{ "r5", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[5]) },
    254	{ "r6", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[6]) },
    255	{ "r7", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[7]) },
    256	{ "r8", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[8]) },
    257	{ "r9", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[9]) },
    258	{ "r10", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[10]) },
    259	{ "r11", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[11]) },
    260	{ "r12", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[12]) },
    261	{ "r13", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[13]) },
    262	{ "r14", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[14]) },
    263	{ "r15", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[15]) },
    264	{ "r16", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[16]) },
    265	{ "r17", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[17]) },
    266	{ "r18", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[18]) },
    267	{ "r19", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[19]) },
    268	{ "r20", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[20]) },
    269	{ "r21", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[21]) },
    270	{ "r22", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[22]) },
    271	{ "r23", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[23]) },
    272	{ "r24", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[24]) },
    273	{ "r25", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[25]) },
    274	{ "r26", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[26]) },
    275	{ "r27", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[27]) },
    276	{ "r28", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[28]) },
    277	{ "r29", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[29]) },
    278	{ "r30", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[30]) },
    279	{ "r31", GDB_SIZEOF_REG, offsetof(struct pt_regs, gpr[31]) },
    280
    281	{ "f0", GDB_SIZEOF_FLOAT_REG, 0 },
    282	{ "f1", GDB_SIZEOF_FLOAT_REG, 1 },
    283	{ "f2", GDB_SIZEOF_FLOAT_REG, 2 },
    284	{ "f3", GDB_SIZEOF_FLOAT_REG, 3 },
    285	{ "f4", GDB_SIZEOF_FLOAT_REG, 4 },
    286	{ "f5", GDB_SIZEOF_FLOAT_REG, 5 },
    287	{ "f6", GDB_SIZEOF_FLOAT_REG, 6 },
    288	{ "f7", GDB_SIZEOF_FLOAT_REG, 7 },
    289	{ "f8", GDB_SIZEOF_FLOAT_REG, 8 },
    290	{ "f9", GDB_SIZEOF_FLOAT_REG, 9 },
    291	{ "f10", GDB_SIZEOF_FLOAT_REG, 10 },
    292	{ "f11", GDB_SIZEOF_FLOAT_REG, 11 },
    293	{ "f12", GDB_SIZEOF_FLOAT_REG, 12 },
    294	{ "f13", GDB_SIZEOF_FLOAT_REG, 13 },
    295	{ "f14", GDB_SIZEOF_FLOAT_REG, 14 },
    296	{ "f15", GDB_SIZEOF_FLOAT_REG, 15 },
    297	{ "f16", GDB_SIZEOF_FLOAT_REG, 16 },
    298	{ "f17", GDB_SIZEOF_FLOAT_REG, 17 },
    299	{ "f18", GDB_SIZEOF_FLOAT_REG, 18 },
    300	{ "f19", GDB_SIZEOF_FLOAT_REG, 19 },
    301	{ "f20", GDB_SIZEOF_FLOAT_REG, 20 },
    302	{ "f21", GDB_SIZEOF_FLOAT_REG, 21 },
    303	{ "f22", GDB_SIZEOF_FLOAT_REG, 22 },
    304	{ "f23", GDB_SIZEOF_FLOAT_REG, 23 },
    305	{ "f24", GDB_SIZEOF_FLOAT_REG, 24 },
    306	{ "f25", GDB_SIZEOF_FLOAT_REG, 25 },
    307	{ "f26", GDB_SIZEOF_FLOAT_REG, 26 },
    308	{ "f27", GDB_SIZEOF_FLOAT_REG, 27 },
    309	{ "f28", GDB_SIZEOF_FLOAT_REG, 28 },
    310	{ "f29", GDB_SIZEOF_FLOAT_REG, 29 },
    311	{ "f30", GDB_SIZEOF_FLOAT_REG, 30 },
    312	{ "f31", GDB_SIZEOF_FLOAT_REG, 31 },
    313
    314	{ "pc", GDB_SIZEOF_REG, offsetof(struct pt_regs, nip) },
    315	{ "msr", GDB_SIZEOF_REG, offsetof(struct pt_regs, msr) },
    316	{ "cr", GDB_SIZEOF_REG_U32, offsetof(struct pt_regs, ccr) },
    317	{ "lr", GDB_SIZEOF_REG, offsetof(struct pt_regs, link) },
    318	{ "ctr", GDB_SIZEOF_REG_U32, offsetof(struct pt_regs, ctr) },
    319	{ "xer", GDB_SIZEOF_REG, offsetof(struct pt_regs, xer) },
    320};
    321
    322char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
    323{
    324	if (regno >= DBG_MAX_REG_NUM || regno < 0)
    325		return NULL;
    326
    327	if (regno < 32 || regno >= 64)
    328		/* First 0 -> 31 gpr registers*/
    329		/* pc, msr, ls... registers 64 -> 69 */
    330		memcpy(mem, (void *)regs + dbg_reg_def[regno].offset,
    331				dbg_reg_def[regno].size);
    332
    333	if (regno >= 32 && regno < 64) {
    334		/* FP registers 32 -> 63 */
    335#if defined(CONFIG_FSL_BOOKE) && defined(CONFIG_SPE)
    336		if (current)
    337			memcpy(mem, &current->thread.evr[regno-32],
    338					dbg_reg_def[regno].size);
    339#else
    340		/* fp registers not used by kernel, leave zero */
    341		memset(mem, 0, dbg_reg_def[regno].size);
    342#endif
    343	}
    344
    345	return dbg_reg_def[regno].name;
    346}
    347
    348int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
    349{
    350	if (regno >= DBG_MAX_REG_NUM || regno < 0)
    351		return -EINVAL;
    352
    353	if (regno < 32 || regno >= 64)
    354		/* First 0 -> 31 gpr registers*/
    355		/* pc, msr, ls... registers 64 -> 69 */
    356		memcpy((void *)regs + dbg_reg_def[regno].offset, mem,
    357				dbg_reg_def[regno].size);
    358
    359	if (regno >= 32 && regno < 64) {
    360		/* FP registers 32 -> 63 */
    361#if defined(CONFIG_FSL_BOOKE) && defined(CONFIG_SPE)
    362		memcpy(&current->thread.evr[regno-32], mem,
    363				dbg_reg_def[regno].size);
    364#else
    365		/* fp registers not used by kernel, leave zero */
    366		return 0;
    367#endif
    368	}
    369
    370	return 0;
    371}
    372
    373void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
    374{
    375	regs_set_return_ip(regs, pc);
    376}
    377
    378/*
    379 * This function does PowerPC specific processing for interfacing to gdb.
    380 */
    381int kgdb_arch_handle_exception(int vector, int signo, int err_code,
    382			       char *remcom_in_buffer, char *remcom_out_buffer,
    383			       struct pt_regs *linux_regs)
    384{
    385	char *ptr = &remcom_in_buffer[1];
    386	unsigned long addr;
    387
    388	switch (remcom_in_buffer[0]) {
    389		/*
    390		 * sAA..AA   Step one instruction from AA..AA
    391		 * This will return an error to gdb ..
    392		 */
    393	case 's':
    394	case 'c':
    395		/* handle the optional parameter */
    396		if (kgdb_hex2long(&ptr, &addr))
    397			regs_set_return_ip(linux_regs, addr);
    398
    399		atomic_set(&kgdb_cpu_doing_single_step, -1);
    400		/* set the trace bit if we're stepping */
    401		if (remcom_in_buffer[0] == 's') {
    402#ifdef CONFIG_PPC_ADV_DEBUG_REGS
    403			mtspr(SPRN_DBCR0,
    404			      mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
    405			regs_set_return_msr(linux_regs, linux_regs->msr | MSR_DE);
    406#else
    407			regs_set_return_msr(linux_regs, linux_regs->msr | MSR_SE);
    408#endif
    409			atomic_set(&kgdb_cpu_doing_single_step,
    410				   raw_smp_processor_id());
    411		}
    412		return 0;
    413	}
    414
    415	return -1;
    416}
    417
    418int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
    419{
    420	u32 instr, *addr = (u32 *)bpt->bpt_addr;
    421	int err;
    422
    423	err = get_kernel_nofault(instr, addr);
    424	if (err)
    425		return err;
    426
    427	err = patch_instruction(addr, ppc_inst(BREAK_INSTR));
    428	if (err)
    429		return -EFAULT;
    430
    431	*(u32 *)bpt->saved_instr = instr;
    432
    433	return 0;
    434}
    435
    436int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt)
    437{
    438	int err;
    439	unsigned int instr = *(unsigned int *)bpt->saved_instr;
    440	u32 *addr = (u32 *)bpt->bpt_addr;
    441
    442	err = patch_instruction(addr, ppc_inst(instr));
    443	if (err)
    444		return -EFAULT;
    445
    446	return 0;
    447}
    448
    449/*
    450 * Global data
    451 */
    452const struct kgdb_arch arch_kgdb_ops;
    453
    454static int kgdb_not_implemented(struct pt_regs *regs)
    455{
    456	return 0;
    457}
    458
    459static void *old__debugger_ipi;
    460static void *old__debugger;
    461static void *old__debugger_bpt;
    462static void *old__debugger_sstep;
    463static void *old__debugger_iabr_match;
    464static void *old__debugger_break_match;
    465static void *old__debugger_fault_handler;
    466
    467int kgdb_arch_init(void)
    468{
    469	old__debugger_ipi = __debugger_ipi;
    470	old__debugger = __debugger;
    471	old__debugger_bpt = __debugger_bpt;
    472	old__debugger_sstep = __debugger_sstep;
    473	old__debugger_iabr_match = __debugger_iabr_match;
    474	old__debugger_break_match = __debugger_break_match;
    475	old__debugger_fault_handler = __debugger_fault_handler;
    476
    477	__debugger_ipi = kgdb_debugger_ipi;
    478	__debugger = kgdb_debugger;
    479	__debugger_bpt = kgdb_handle_breakpoint;
    480	__debugger_sstep = kgdb_singlestep;
    481	__debugger_iabr_match = kgdb_iabr_match;
    482	__debugger_break_match = kgdb_break_match;
    483	__debugger_fault_handler = kgdb_not_implemented;
    484
    485	return 0;
    486}
    487
    488void kgdb_arch_exit(void)
    489{
    490	__debugger_ipi = old__debugger_ipi;
    491	__debugger = old__debugger;
    492	__debugger_bpt = old__debugger_bpt;
    493	__debugger_sstep = old__debugger_sstep;
    494	__debugger_iabr_match = old__debugger_iabr_match;
    495	__debugger_break_match = old__debugger_break_match;
    496	__debugger_fault_handler = old__debugger_fault_handler;
    497}