⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 traps.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <xen/config.h>#include <xen/version.h>#include <xen/domain_page.h>#include <xen/init.h>#include <xen/sched.h>#include <xen/lib.h>#include <xen/console.h>#include <xen/mm.h>#include <xen/irq.h>#include <xen/symbols.h>#include <xen/shutdown.h>#include <xen/nmi.h>#include <asm/current.h>#include <asm/flushtlb.h>#include <asm/hvm/hvm.h>#include <asm/hvm/support.h>#include <public/callback.h>static void print_xen_info(void){    char taint_str[TAINT_STRING_MAX_LEN];    char debug = 'n', *arch = "x86_32p";#ifndef NDEBUG    debug = 'y';#endif    printk("----[ Xen-%d.%d%s  %s  debug=%c  %s ]----\n",           xen_major_version(), xen_minor_version(), xen_extra_version(),           arch, debug, print_tainted(taint_str));}enum context { CTXT_hypervisor, CTXT_pv_guest, CTXT_hvm_guest };static void _show_registers(    const struct cpu_user_regs *regs, unsigned long crs[8],    enum context context, const struct vcpu *v){    const static char *context_names[] = {        [CTXT_hypervisor] = "hypervisor",        [CTXT_pv_guest]   = "pv guest",        [CTXT_hvm_guest]  = "hvm guest"    };    printk("EIP:    %04x:[<%08x>]", regs->cs, regs->eip);    if ( context == CTXT_hypervisor )        print_symbol(" %s", regs->eip);    printk("\nEFLAGS: %08x   ", regs->eflags);    if ( (context == CTXT_pv_guest) && v && v->vcpu_info )        printk("EM: %d   ", !!v->vcpu_info->evtchn_upcall_mask);    printk("CONTEXT: %s\n", context_names[context]);    printk("eax: %08x   ebx: %08x   ecx: %08x   edx: %08x\n",           regs->eax, regs->ebx, regs->ecx, regs->edx);    printk("esi: %08x   edi: %08x   ebp: %08x   esp: %08x\n",           regs->esi, regs->edi, regs->ebp, regs->esp);    printk("cr0: %08lx   cr4: %08lx   cr3: %08lx   cr2: %08lx\n",           crs[0], crs[4], crs[3], crs[2]);    printk("ds: %04x   es: %04x   fs: %04x   gs: %04x   "           "ss: %04x   cs: %04x\n",           regs->ds, regs->es, regs->fs,           regs->gs, regs->ss, regs->cs);}void show_registers(struct cpu_user_regs *regs){    struct cpu_user_regs fault_regs = *regs;    unsigned long fault_crs[8];    enum context context;    struct vcpu *v = current;    if ( is_hvm_vcpu(v) && guest_mode(regs) )    {        struct segment_register sreg;        context = CTXT_hvm_guest;        fault_crs[0] = v->arch.hvm_vcpu.guest_cr[0];        fault_crs[2] = v->arch.hvm_vcpu.guest_cr[2];        fault_crs[3] = v->arch.hvm_vcpu.guest_cr[3];        fault_crs[4] = v->arch.hvm_vcpu.guest_cr[4];        hvm_get_segment_register(v, x86_seg_cs, &sreg);        fault_regs.cs = sreg.sel;        hvm_get_segment_register(v, x86_seg_ds, &sreg);        fault_regs.ds = sreg.sel;        hvm_get_segment_register(v, x86_seg_es, &sreg);        fault_regs.es = sreg.sel;        hvm_get_segment_register(v, x86_seg_fs, &sreg);        fault_regs.fs = sreg.sel;        hvm_get_segment_register(v, x86_seg_gs, &sreg);        fault_regs.gs = sreg.sel;        hvm_get_segment_register(v, x86_seg_ss, &sreg);        fault_regs.ss = sreg.sel;    }    else    {        if ( !guest_mode(regs) )        {            context = CTXT_hypervisor;            fault_regs.esp = (unsigned long)&regs->esp;            fault_regs.ss = read_segment_register(ss);            fault_regs.ds = read_segment_register(ds);            fault_regs.es = read_segment_register(es);            fault_regs.fs = read_segment_register(fs);            fault_regs.gs = read_segment_register(gs);            fault_crs[2] = read_cr2();        }        else        {            context = CTXT_pv_guest;            fault_crs[2] = v->vcpu_info->arch.cr2;        }        fault_crs[0] = read_cr0();        fault_crs[3] = read_cr3();        fault_crs[4] = read_cr4();    }    print_xen_info();    printk("CPU:    %d\n", smp_processor_id());    _show_registers(&fault_regs, fault_crs, context, v);    if ( this_cpu(ler_msr) && !guest_mode(regs) )    {        u32 from, to, hi;        rdmsr(this_cpu(ler_msr), from, hi);        rdmsr(this_cpu(ler_msr) + 1, to, hi);        printk("ler: %08x -> %08x\n", from, to);    }}void vcpu_show_registers(const struct vcpu *v){    unsigned long crs[8];    /* No need to handle HVM for now. */    if ( is_hvm_vcpu(v) )        return;    crs[0] = v->arch.guest_context.ctrlreg[0];    crs[2] = v->vcpu_info->arch.cr2;    crs[3] = pagetable_get_paddr(v->arch.guest_table);    crs[4] = v->arch.guest_context.ctrlreg[4];    _show_registers(&v->arch.guest_context.user_regs, crs, CTXT_pv_guest, v);}void show_page_walk(unsigned long addr){    unsigned long pfn, mfn, cr3 = read_cr3();    l3_pgentry_t l3e, *l3t;    l2_pgentry_t l2e, *l2t;    l1_pgentry_t l1e, *l1t;    printk("Pagetable walk from %08lx:\n", addr);    mfn = cr3 >> PAGE_SHIFT;    l3t  = map_domain_page(mfn);    l3t += (cr3 & 0xFE0UL) >> 3;    l3e = l3t[l3_table_offset(addr)];    mfn = l3e_get_pfn(l3e);    pfn = mfn_valid(mfn) ? get_gpfn_from_mfn(mfn) : INVALID_M2P_ENTRY;    printk(" L3[0x%03lx] = %"PRIpte" %08lx\n",           l3_table_offset(addr), l3e_get_intpte(l3e), pfn);    unmap_domain_page(l3t);    if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) )        return;    l2t = map_domain_page(mfn);    l2e = l2t[l2_table_offset(addr)];    mfn = l2e_get_pfn(l2e);    pfn = mfn_valid(mfn) ? get_gpfn_from_mfn(mfn) : INVALID_M2P_ENTRY;    printk(" L2[0x%03lx] = %"PRIpte" %08lx %s\n",           l2_table_offset(addr), l2e_get_intpte(l2e), pfn,           (l2e_get_flags(l2e) & _PAGE_PSE) ? "(PSE)" : "");    unmap_domain_page(l2t);    if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) ||         (l2e_get_flags(l2e) & _PAGE_PSE) )        return;    l1t = map_domain_page(mfn);    l1e = l1t[l1_table_offset(addr)];    mfn = l1e_get_pfn(l1e);    pfn = mfn_valid(mfn) ? get_gpfn_from_mfn(mfn) : INVALID_M2P_ENTRY;    printk(" L1[0x%03lx] = %"PRIpte" %08lx\n",           l1_table_offset(addr), l1e_get_intpte(l1e), pfn);    unmap_domain_page(l1t);}#define DOUBLEFAULT_STACK_SIZE 2048static struct tss_struct doublefault_tss;static unsigned char doublefault_stack[DOUBLEFAULT_STACK_SIZE];asmlinkage void do_double_fault(void){    struct tss_struct *tss = &doublefault_tss;    unsigned int cpu = ((tss->back_link>>3)-__FIRST_TSS_ENTRY)>>1;    watchdog_disable();    console_force_unlock();    /* Find information saved during fault and dump it to the console. */    tss = &init_tss[cpu];    printk("*** DOUBLE FAULT ***\n");    print_xen_info();    printk("CPU:    %d\nEIP:    %04x:[<%08x>]",           cpu, tss->cs, tss->eip);    print_symbol(" %s\n", tss->eip);    printk("EFLAGS: %08x\n", tss->eflags);    printk("CR3:    %08x\n", tss->__cr3);    printk("eax: %08x   ebx: %08x   ecx: %08x   edx: %08x\n",           tss->eax, tss->ebx, tss->ecx, tss->edx);    printk("esi: %08x   edi: %08x   ebp: %08x   esp: %08x\n",           tss->esi, tss->edi, tss->ebp, tss->esp);    printk("ds: %04x   es: %04x   fs: %04x   gs: %04x   ss: %04x\n",           tss->ds, tss->es, tss->fs, tss->gs, tss->ss);    show_stack_overflow(cpu, tss->esp);    panic("DOUBLE FAULT -- system shutdown\n");}unsigned long do_iret(void){    struct cpu_user_regs *regs = guest_cpu_user_regs();    struct vcpu *v = current;    u32 eflags;    /* Check worst-case stack frame for overlap with Xen protected area. */    if ( unlikely(!access_ok(regs->esp, 40)) )        goto exit_and_crash;    /* Pop and restore EAX (clobbered by hypercall). */    if ( unlikely(__copy_from_user(&regs->eax, (void *)regs->esp, 4)) )        goto exit_and_crash;    regs->esp += 4;    /* Pop and restore CS and EIP. */    if ( unlikely(__copy_from_user(&regs->eip, (void *)regs->esp, 8)) )        goto exit_and_crash;    regs->esp += 8;    /*     * Pop, fix up and restore EFLAGS. We fix up in a local staging area     * to avoid firing the BUG_ON(IOPL) check in arch_get_info_guest.     */    if ( unlikely(__copy_from_user(&eflags, (void *)regs->esp, 4)) )        goto exit_and_crash;    regs->esp += 4;    regs->eflags = (eflags & ~X86_EFLAGS_IOPL) | X86_EFLAGS_IF;    if ( vm86_mode(regs) )    {        /* Return to VM86 mode: pop and restore ESP,SS,ES,DS,FS and GS. */        if ( __copy_from_user(&regs->esp, (void *)regs->esp, 24) )            goto exit_and_crash;    }    else if ( unlikely(ring_0(regs)) )    {        goto exit_and_crash;    }    else if ( !ring_1(regs) )    {        /* Return to ring 2/3: pop and restore ESP and SS. */        if ( __copy_from_user(&regs->esp, (void *)regs->esp, 8) )            goto exit_and_crash;    }    /* Restore affinity.  */    if ((v->trap_priority >= VCPU_TRAP_NMI)       && !cpus_equal(v->cpu_affinity_tmp, v->cpu_affinity))        vcpu_set_affinity(v, &v->cpu_affinity_tmp);    /* Restore previous trap priority */    v->trap_priority = v->old_trap_priority;    /* Restore upcall mask from supplied EFLAGS.IF. */    vcpu_info(v, evtchn_upcall_mask) = !(eflags & X86_EFLAGS_IF);    /*     * The hypercall exit path will overwrite EAX with this return     * value.     */    return regs->eax; exit_and_crash:    gdprintk(XENLOG_ERR, "Fatal error\n");    domain_crash(v->domain);    return 0;}static void set_task_gate(unsigned int n, unsigned int sel){    idt_table[n].b = 0;    wmb(); /* disable gate /then/ rewrite */    idt_table[n].a = sel << 16;    wmb(); /* rewrite /then/ enable gate */    idt_table[n].b = 0x8500;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -