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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
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, &regs->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");
}
Beispiel #7
0
void *dereference_function_descriptor(void *ptr)
{
	Elf64_Fdesc *desc = ptr;
	void *p;

	if (!probe_kernel_address(&desc->addr, p))
		ptr = p;
	return ptr;
}
Beispiel #8
0
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, &regs->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");
}
Beispiel #10
0
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;
}
Beispiel #12
0
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;
}
Beispiel #16
0
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;
}
Beispiel #18
0
/*
 * 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");
	}
}
Beispiel #19
0
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;
	}
}
Beispiel #20
0
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;
	}
}