Exemple #1
0
static int isr_hooker_init(void)
{
	gate_desc *old_idt, *new_idt;
	unsigned long new_idt_page;

	pr_info("%s\n", __func__);

	/* obtain IDT descriptor */
	store_idt(&old_idtr);
	old_idt = (gate_desc *)old_idtr.address;

	/* prepare new IDT */
	new_idt_page = __get_free_page(GFP_KERNEL);
	if(!new_idt_page)
		return -ENOMEM;

	new_idtr.address = new_idt_page;
	new_idtr.size = old_idtr.size;
	new_idt = (gate_desc *)new_idtr.address;

	memcpy(new_idt, old_idt, old_idtr.size);

	/* modify the target entry */
	orig_isr = gate_offset(new_idt[TRAP_NR]);
	pr_info("orig_isr@%p\n", (void*)orig_isr);
	pack_gate(&new_idt[TRAP_NR], GATE_INTERRUPT, (unsigned long)stub, 0, 0, __KERNEL_CS);

	/* setup new entry */
	load_idt((void *)&new_idtr);
	smp_call_function((smp_call_func_t)load_idt, &new_idtr, 1);

	return 0;
}
Exemple #2
0
static int cvt_gate_to_trap(int vector, const gate_desc *val,
			    struct trap_info *info)
{
	unsigned long addr;

	if (val->type != GATE_TRAP && val->type != GATE_INTERRUPT)
		return 0;

	info->vector = vector;

	addr = gate_offset(*val);
#ifdef CONFIG_X86_64
	/*
	 * Look for known traps using IST, and substitute them
	 * appropriately.  The debugger ones are the only ones we care
	 * about.  Xen will handle faults like double_fault,
	 * so we should never see them.  Warn if
	 * there's an unexpected IST-using fault handler.
	 */
	if (addr == (unsigned long)debug)
		addr = (unsigned long)xen_debug;
	else if (addr == (unsigned long)int3)
		addr = (unsigned long)xen_int3;
	else if (addr == (unsigned long)stack_segment)
		addr = (unsigned long)xen_stack_segment;
	else if (addr == (unsigned long)double_fault ||
		 addr == (unsigned long)nmi) {
		/* Don't need to handle these */
		return 0;
#ifdef CONFIG_X86_MCE
	} else if (addr == (unsigned long)machine_check) {
		/*
		 * when xen hypervisor inject vMCE to guest,
		 * use native mce handler to handle it
		 */
		;
#endif
	} else {
		/* Some other trap using IST? */
		if (WARN_ON(val->ist != 0))
			return 0;
	}
#endif	/* CONFIG_X86_64 */
	info->address = addr;

	info->cs = gate_segment(*val);
	info->flags = val->dpl;
	/* interrupt gates clear IF */
	if (val->type == GATE_INTERRUPT)
		info->flags |= 1 << 2;

	return 1;
}
Exemple #3
0
void ltt_dump_idt_table(void *call_data)
{
	int i;
	char namebuf[KSYM_NAME_LEN];

	for (i = 0; i < IDT_ENTRIES; i++) {
		unsigned long address = gate_offset(idt_table[i]);
		sprint_symbol(namebuf, address);
		__trace_mark(0, irq_state, idt_table, call_data,
			"irq %d address %p symbol %s",
			i, (void *)address, namebuf);
	}
}
static int cvt_gate_to_trap(int vector, const gate_desc *val,
			    struct trap_info *info)
{
	unsigned long addr;

	if (val->type != GATE_TRAP && val->type != GATE_INTERRUPT)
		return 0;

	info->vector = vector;

	addr = gate_offset(*val);
#ifdef CONFIG_X86_64
	/*
                                                       
                                                               
                                                        
                                                        
                                                  
  */
	if (addr == (unsigned long)debug)
		addr = (unsigned long)xen_debug;
	else if (addr == (unsigned long)int3)
		addr = (unsigned long)xen_int3;
	else if (addr == (unsigned long)stack_segment)
		addr = (unsigned long)xen_stack_segment;
	else if (addr == (unsigned long)double_fault ||
		 addr == (unsigned long)nmi) {
		/*                            */
		return 0;
#ifdef CONFIG_X86_MCE
	} else if (addr == (unsigned long)machine_check) {
		return 0;
#endif
	} else {
		/*                            */
		if (WARN_ON(val->ist != 0))
			return 0;
	}
#endif	/*               */
	info->address = addr;

	info->cs = gate_segment(*val);
	info->flags = val->dpl;
	/*                          */
	if (val->type == GATE_INTERRUPT)
		info->flags |= 1 << 2;

	return 1;
}
Exemple #5
0
static int cvt_gate_to_trap(int vector, const gate_desc *val,
			    struct trap_info *info)
{
	if (val->type != GATE_TRAP && val->type != GATE_INTERRUPT)
		return 0;

	info->vector = vector;
	info->address = gate_offset(*val);
	info->cs = gate_segment(*val);
	info->flags = val->dpl;
	/* interrupt gates clear IF */
	if (val->type == GATE_INTERRUPT)
		info->flags |= 1 << 2;

	return 1;
}