void show_registers(struct pt_regs *regs) { int i; unsigned long sp; const int cpu = smp_processor_id(); struct task_struct *cur = current; sp = regs->sp; printk("CPU %d ", cpu); print_modules(); __show_regs(regs, 1); printk("Process %s (pid: %d, veid: %d, threadinfo %p, task %p)\n", cur->comm, cur->pid, task_veid(cur), task_thread_info(cur), cur); /* * When in-kernel, we also print out the stack and code at the * time of the fault.. */ if (!user_mode(regs)) { unsigned int code_prologue = code_bytes * 43 / 64; unsigned int code_len = code_bytes; unsigned char c; u8 *ip; printk(KERN_DEFAULT "Stack:\n"); show_stack_log_lvl(NULL, regs, (unsigned long *)sp, KERN_DEFAULT); printk(KERN_DEFAULT "Code: "); ip = (u8 *)regs->ip - code_prologue; if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { /* try starting at IP */ ip = (u8 *)regs->ip; code_len = code_len - code_prologue + 1; } for (i = 0; i < code_len; i++, ip++) { if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { printk(" Bad RIP value."); break; } if (ip == (u8 *)regs->ip) printk("<%02x> ", c); else printk("%02x ", c); } } printk("\n"); }
static int __init romsignature(const unsigned char *rom) { const unsigned short * const ptr = (const unsigned short *)rom; unsigned short sig; return probe_kernel_address(ptr, sig) == 0 && sig == ROMSIGNATURE; }
void show_regs(struct pt_regs *regs) { int i; unsigned long sp; sp = regs->sp; show_regs_print_info(KERN_DEFAULT); __show_regs(regs, 1); /* * When in-kernel, we also print out the stack and code at the * time of the fault.. */ if (!user_mode(regs)) { unsigned int code_prologue = code_bytes * 43 / 64; unsigned int code_len = code_bytes; unsigned char c; u8 *ip; show_lbrs(); /* called before show_stack_log_lvl() as it could trig page_fault again and reenable LBR */ printk(KERN_DEFAULT "Stack:\n"); show_stack_log_lvl(NULL, regs, (unsigned long *)sp, 0, KERN_DEFAULT); printk(KERN_DEFAULT "Code: "); ip = (u8 *)regs->ip - code_prologue; if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { /* try starting at IP */ ip = (u8 *)regs->ip; code_len = code_len - code_prologue + 1; } for (i = 0; i < code_len; i++, ip++) { if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { pr_cont(" Bad RIP value."); break; } if (ip == (u8 *)regs->ip) pr_cont("<%02x> ", c); else pr_cont("%02x ", c); } } pr_cont("\n"); }
static int __init romchecksum(const unsigned char *rom, unsigned long length) { unsigned char sum, c; for (sum = 0; length && probe_kernel_address(rom++, c) == 0; length--) sum += c; return !length && !sum; }
static __kprobes unsigned long fetch_memory(struct pt_regs *regs, void *addr) { unsigned long retval; if (probe_kernel_address(addr, retval)) return 0; return retval; }
void show_registers(struct pt_regs *regs) { int i; print_modules(); __show_regs(regs, 0); printk(KERN_EMERG "Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)\n", TASK_COMM_LEN, current->comm, task_pid_nr(current), current_thread_info(), current, task_thread_info(current)); /* * When in-kernel, we also print out the stack and code at the * time of the fault.. */ if (!user_mode_vm(regs)) { unsigned int code_prologue = code_bytes * 43 / 64; unsigned int code_len = code_bytes; unsigned char c; u8 *ip; printk(KERN_EMERG "Stack:\n"); show_stack_log_lvl(NULL, regs, ®s->sp, 0, KERN_EMERG); printk(KERN_EMERG "Code: "); ip = (u8 *)regs->ip - code_prologue; if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { /* try starting at IP */ ip = (u8 *)regs->ip; code_len = code_len - code_prologue + 1; } for (i = 0; i < code_len; i++, ip++) { if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { printk(" Bad EIP value."); break; } if (ip == (u8 *)regs->ip) printk("<%02x> ", c); else printk("%02x ", c); } } printk("\n"); }
void *dereference_function_descriptor(void *ptr) { Elf64_Fdesc *desc = ptr; void *p; if (!probe_kernel_address(&desc->addr, p)) ptr = p; return ptr; }
int is_valid_bugaddr(unsigned long eip) { unsigned short ud2; if (probe_kernel_address((unsigned short __user *)eip, ud2)) return 0; return ud2 == 0x0b0f; }
void show_regs(struct pt_regs *regs) { int i; show_regs_print_info(KERN_EMERG); __show_regs(regs, !user_mode(regs)); /* * When in-kernel, we also print out the stack and code at the * time of the fault.. */ if (!user_mode(regs)) { unsigned int code_prologue = code_bytes * 43 / 64; unsigned int code_len = code_bytes; unsigned char c; u8 *ip; pr_emerg("Stack:\n"); show_stack_log_lvl(NULL, regs, ®s->sp, 0, KERN_EMERG); pr_emerg("Code:"); ip = (u8 *)regs->ip - code_prologue; if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { /* try starting at IP */ ip = (u8 *)regs->ip; code_len = code_len - code_prologue + 1; } for (i = 0; i < code_len; i++, ip++) { if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) { pr_cont(" Bad EIP value."); break; } if (ip == (u8 *)regs->ip) pr_cont(" <%02x>", c); else pr_cont(" %02x", c); } } pr_cont("\n"); }
int is_valid_bugaddr(unsigned long addr) { unsigned short opcode; if (addr < PAGE_OFFSET) return 0; if (probe_kernel_address((u16 *)addr, opcode)) return 0; return opcode == TRAPA_BUG_OPCODE; }
int is_valid_bugaddr(unsigned long ip) { unsigned short ud2; if (ip < PAGE_OFFSET) return 0; if (probe_kernel_address((unsigned short *)ip, ud2)) return 0; return ud2 == 0x0b0f; }
int is_valid_bugaddr(unsigned long addr) { insn_size_t opcode; if (addr < PAGE_OFFSET) return 0; if (probe_kernel_address((insn_size_t *)addr, opcode)) return 0; if (opcode == TRAPA_BUG_OPCODE) return 1; return 0; }
static struct resource *find_oprom(struct pci_dev *pdev) { struct resource *oprom = NULL; int i; for (i = 0; i < ARRAY_SIZE(adapter_rom_resources); i++) { struct resource *res = &adapter_rom_resources[i]; unsigned short offset, vendor, device, list, rev; const unsigned char *rom; if (res->end == 0) break; rom = isa_bus_to_virt(res->start); if (probe_kernel_address(rom + 0x18, offset) != 0) continue; if (probe_kernel_address(rom + offset + 0x4, vendor) != 0) continue; if (probe_kernel_address(rom + offset + 0x6, device) != 0) continue; if (match_id(pdev, vendor, device)) { oprom = res; break; } if (probe_kernel_address(rom + offset + 0x8, list) == 0 && probe_kernel_address(rom + offset + 0xc, rev) == 0 && rev >= 3 && list && probe_list(pdev, vendor, rom + offset + list)) { oprom = res; break; } } return oprom; }
void show_memory(unsigned long addr_in, unsigned int nbytes, int ibool) { int i, j; u32 *p; unsigned long virtual_addr; unsigned int itotalbytes = nbytes; const unsigned int line_size = 32; unsigned int nlines; unsigned int size; printk("\naddress 0x%lx:\n", addr_in); /*vir addr*/ if (ibool) { virtual_addr = addr_in; /* round address down to a 32/64 bit boundary */ p = (u32 *)(virtual_addr & ~(sizeof(unsigned long) - 1)); /* always dump a multiple of 32 bytes */ itotalbytes += (virtual_addr & (sizeof(unsigned long) - 1)); nlines = (itotalbytes + (line_size-1)) / line_size; for (i=0; i<nlines; i++) { /* * just display low 16 bits of address to keep * each line of the dump < 80 characters */ printk("%04lx ", (unsigned long)p & 0xffff); for (j=0; j < line_size/sizeof(u32); j++) { u32 data; if (probe_kernel_address(p++, data)) { printk(" ********"); } else { printk(" %08x", data); } } printk("\n"); } }else { /*phy addr*/ /* always dump a multiple of 32 bytes */ nlines = (itotalbytes + (line_size-1)) / line_size; size = nlines*line_size / sizeof(u32); reg_dbg_dump(addr_in, size, sizeof(u32)); } }
static bool probe_list(struct pci_dev *pdev, unsigned short vendor, const unsigned char *rom_list) { unsigned short device; do { if (probe_kernel_address(rom_list, device) != 0) device = 0; if (device && match_id(pdev, vendor, device)) break; rom_list += 2; } while (device); return !!device; }
static int call_undef_hook(struct pt_regs *regs) { struct undef_hook *hook; unsigned long flags; u32 instr; int (*fn)(struct pt_regs *regs, u32 instr) = NULL; void __user *pc = (void __user *)instruction_pointer(regs); if (!user_mode(regs)) { __le32 instr_le; if (probe_kernel_address((__force __le32 *)pc, instr_le)) goto exit; instr = le32_to_cpu(instr_le); } else if (compat_thumb_mode(regs)) { /* 16-bit Thumb instruction */ __le16 instr_le; if (get_user(instr_le, (__le16 __user *)pc)) goto exit; instr = le16_to_cpu(instr_le); if (aarch32_insn_is_wide(instr)) { u32 instr2; if (get_user(instr_le, (__le16 __user *)(pc + 2))) goto exit; instr2 = le16_to_cpu(instr_le); instr = (instr << 16) | instr2; } } else { /* 32-bit ARM instruction */ __le32 instr_le; if (get_user(instr_le, (__le32 __user *)pc)) goto exit; instr = le32_to_cpu(instr_le); } raw_spin_lock_irqsave(&undef_lock, flags); list_for_each_entry(hook, &undef_hook, node) if ((instr & hook->instr_mask) == hook->instr_val && (regs->pstate & hook->pstate_mask) == hook->pstate_val) fn = hook->fn; raw_spin_unlock_irqrestore(&undef_lock, flags); exit: return fn ? fn(regs, instr) : 1; }
/* * We are returning from the irq stack and go to the previous one. * If the previous stack is also in the irq stack, then bp in the first * frame of the irq stack points to the previous, interrupted one. * Otherwise we have another level of indirection: We first save * the bp of the previous stack, then we switch the stack to the irq one * and save a new bp that links to the previous one. * (See save_args()) */ static inline unsigned long fixup_bp_irq_link(unsigned long bp, unsigned long *stack, unsigned long *irq_stack, unsigned long *irq_stack_end) { #ifdef CONFIG_FRAME_POINTER struct stack_frame *frame = (struct stack_frame *)bp; unsigned long next; if (!in_irq_stack(stack, irq_stack, irq_stack_end)) { if (!probe_kernel_address(&frame->next_frame, next)) return next; else WARN_ONCE(1, "Perf: bad frame pointer = %p in " "callchain\n", &frame->next_frame); } #endif return bp; }
/* * dump a block of kernel memory from around the given address */ static void show_data(unsigned long addr, int nbytes, const char *name) { int i, j; int nlines; u32 *p; /* * don't attempt to dump non-kernel addresses or * values that are probably just small negative numbers */ if (addr < PAGE_OFFSET || addr > -256UL) return; printk("\n%s: %#lx:\n", name, addr); /* * round address down to a 32 bit boundary * and always dump a multiple of 32 bytes */ p = (u32 *)(addr & ~(sizeof(u32) - 1)); nbytes += (addr & (sizeof(u32) - 1)); nlines = (nbytes + 31) / 32; for (i = 0; i < nlines; i++) { /* * just display low 16 bits of address to keep * each line of the dump < 80 characters */ printk("%04lx ", (unsigned long)p & 0xffff); for (j = 0; j < 8; j++) { u32 data; if (in_nmi() || probe_kernel_address(p, data)) { printk(" ********"); } else { printk(" %08x", data); } ++p; } printk("\n"); } }
void __init probe_roms(void) { const unsigned char *rom; unsigned long start, length, upper; unsigned char c; int i; /* video rom */ upper = adapter_rom_resources[0].start; for (start = video_rom_resource.start; start < upper; start += 2048) { rom = isa_bus_to_virt(start); if (!romsignature(rom)) continue; video_rom_resource.start = start; if (probe_kernel_address(rom + 2, c) != 0) continue; /* 0 < length <= 0x7f * 512, historically */ length = c * 512; /* if checksum okay, trust length byte */ if (length && romchecksum(rom, length)) video_rom_resource.end = start + length - 1; request_resource(&iomem_resource, &video_rom_resource); break; } start = (video_rom_resource.end + 1 + 2047) & ~2047UL; if (start < upper) start = upper; /* system rom */ request_resource(&iomem_resource, &system_rom_resource); upper = system_rom_resource.start; /* check for extension rom (ignore length byte!) */ rom = isa_bus_to_virt(extension_rom_resource.start); if (romsignature(rom)) { length = resource_size(&extension_rom_resource); if (romchecksum(rom, length)) { request_resource(&iomem_resource, &extension_rom_resource); upper = extension_rom_resource.start; } } /* check for adapter roms on 2k boundaries */ for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; start += 2048) { rom = isa_bus_to_virt(start); if (!romsignature(rom)) continue; if (probe_kernel_address(rom + 2, c) != 0) continue; /* 0 < length <= 0x7f * 512, historically */ length = c * 512; /* but accept any length that fits if checksum okay */ if (!length || start + length > upper || !romchecksum(rom, length)) continue; adapter_rom_resources[i].start = start; adapter_rom_resources[i].end = start + length - 1; request_resource(&iomem_resource, &adapter_rom_resources[i]); start = adapter_rom_resources[i++].end & ~2047UL; } }
static int bad_address(void *p) { unsigned long dummy; return probe_kernel_address((unsigned long*)p, dummy); }
void __init probe_roms(void) { const unsigned char *rom; unsigned long start, length, upper; unsigned char c; int i; /* */ upper = adapter_rom_resources[0].start; for (start = video_rom_resource.start; start < upper; start += 2048) { rom = isa_bus_to_virt(start); if (!romsignature(rom)) continue; video_rom_resource.start = start; if (probe_kernel_address(rom + 2, c) != 0) continue; /* */ length = c * 512; /* */ if (length && romchecksum(rom, length)) video_rom_resource.end = start + length - 1; request_resource(&iomem_resource, &video_rom_resource); break; } start = (video_rom_resource.end + 1 + 2047) & ~2047UL; if (start < upper) start = upper; /* */ request_resource(&iomem_resource, &system_rom_resource); upper = system_rom_resource.start; /* */ rom = isa_bus_to_virt(extension_rom_resource.start); if (romsignature(rom)) { length = resource_size(&extension_rom_resource); if (romchecksum(rom, length)) { request_resource(&iomem_resource, &extension_rom_resource); upper = extension_rom_resource.start; } } /* */ for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; start += 2048) { rom = isa_bus_to_virt(start); if (!romsignature(rom)) continue; if (probe_kernel_address(rom + 2, c) != 0) continue; /* */ length = c * 512; /* */ if (!length || start + length > upper || !romchecksum(rom, length)) continue; adapter_rom_resources[i].start = start; adapter_rom_resources[i].end = start + length - 1; request_resource(&iomem_resource, &adapter_rom_resources[i]); start = adapter_rom_resources[i++].end & ~2047UL; } }