static void doublefault_fn(void) { struct desc_ptr gdt_desc = {0, 0}; unsigned long gdt, tss; native_store_gdt(&gdt_desc); gdt = (unsigned long)gdt_desc.address; printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size); if (ptr_ok(gdt)) { gdt += GDT_ENTRY_TSS << 3; tss = get_desc_base((struct desc_struct *)gdt); printk(KERN_EMERG "double fault, tss at %08lx\n", tss); if (ptr_ok(tss)) { struct x86_hw_tss *t = (struct x86_hw_tss *)tss; printk(KERN_EMERG "eip = %08lx, esp = %08lx\n", t->ip, t->sp); printk(KERN_EMERG "eax = %08lx, ebx = %08lx, ecx = %08lx, edx = %08lx\n", t->ax, t->bx, t->cx, t->dx); printk(KERN_EMERG "esi = %08lx, edi = %08lx\n", t->si, t->di); } } for (;;) cpu_relax(); }
static void fill_user_desc(struct user_desc *info, int idx, const struct desc_struct *desc) { memset(info, 0, sizeof(*info)); info->entry_number = idx; info->base_addr = get_desc_base(desc); info->limit = get_desc_limit(desc); info->seg_32bit = desc->d; info->contents = desc->type >> 2; info->read_exec_only = !(desc->type & 2); info->limit_in_pages = desc->g; info->seg_not_present = !desc->p; info->useable = desc->avl; #ifdef CONFIG_X86_64 info->lm = desc->l; #endif }
/* * Interrupts are disabled on entry as trap3 is an interrupt gate and they * remain disabled thorough out this function. */ static int kprobe_handler(struct pt_regs *regs) { struct kprobe *p; int ret = 0; kprobe_opcode_t *addr = NULL; unsigned long *lp; /* We're in an interrupt, but this is clear and BUG()-safe. */ preempt_disable(); /* Check if the application is using LDT entry for its code segment and * calculate the address by reading the base address from the LDT entry. */ if ((regs->xcs & 4) && (current->mm)) { lp = (unsigned long *) ((unsigned long)((regs->xcs >> 3) * 8) + (char *) current->mm->context.ldt); addr = (kprobe_opcode_t *) (get_desc_base(lp) + regs->eip - sizeof(kprobe_opcode_t)); } else {
unsigned long convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs) { unsigned long addr, seg; addr = regs->ip; seg = regs->cs & 0xffff; if (v8086_mode(regs)) { addr = (addr & 0xffff) + (seg << 4); return addr; } /* * We'll assume that the code segments in the GDT * are all zero-based. That is largely true: the * TLS segments are used for data, and the PNPBIOS * and APM bios ones we just ignore here. */ if ((seg & SEGMENT_TI_MASK) == SEGMENT_LDT) { struct desc_struct *desc; unsigned long base; seg >>= 3; mutex_lock(&child->mm->context.lock); if (unlikely(!child->mm->context.ldt || seg >= child->mm->context.ldt->size)) addr = -1L; /* bogus selector, access would fault */ else { desc = &child->mm->context.ldt->entries[seg]; base = get_desc_base(desc); /* 16-bit code segment? */ if (!desc->d) addr &= 0xffff; addr += base; } mutex_unlock(&child->mm->context.lock); } return addr; }
/* * Interrupts are disabled on entry as trap3 is an interrupt gate and they * remain disabled thorough out this function. */ static int __kprobes kprobe_handler(struct pt_regs *regs) { struct kprobe *p; int ret = 0; kprobe_opcode_t *addr = NULL; unsigned long *lp; struct kprobe_ctlblk *kcb; /* * We don't want to be preempted for the entire * duration of kprobe processing */ preempt_disable(); kcb = get_kprobe_ctlblk(); /* Check if the application is using LDT entry for its code segment and * calculate the address by reading the base address from the LDT entry. */ if ((regs->xcs & 4) && (current->mm)) { lp = (unsigned long *) ((unsigned long)((regs->xcs >> 3) * 8) + (char *) current->mm->context.ldt); addr = (kprobe_opcode_t *) (get_desc_base(lp) + regs->eip - sizeof(kprobe_opcode_t)); } else {