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

📄 traps.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <xen/config.h>#include <xen/version.h>#include <xen/init.h>#include <xen/sched.h>#include <xen/lib.h>#include <xen/errno.h>#include <xen/mm.h>#include <xen/irq.h>#include <xen/symbols.h>#include <xen/console.h>#include <xen/sched.h>#include <xen/shutdown.h>#include <xen/nmi.h>#include <asm/current.h>#include <asm/flushtlb.h>#include <asm/msr.h>#include <asm/page.h>#include <asm/shared.h>#include <asm/hvm/hvm.h>#include <asm/hvm/support.h>#include <public/callback.h>asmlinkage void syscall_enter(void);asmlinkage void sysenter_entry(void);asmlinkage void compat_hypercall(void);asmlinkage void int80_direct_trap(void);static void print_xen_info(void){    char taint_str[TAINT_STRING_MAX_LEN];    char debug = 'n';#ifndef NDEBUG    debug = 'y';#endif    printk("----[ Xen-%d.%d%s  x86_64  debug=%c  %s ]----\n",           xen_major_version(), xen_minor_version(), xen_extra_version(),           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("RIP:    %04x:[<%016lx>]", regs->cs, regs->rip);    if ( context == CTXT_hypervisor )        print_symbol(" %s", regs->rip);    printk("\nRFLAGS: %016lx   ", regs->rflags);    if ( (context == CTXT_pv_guest) && v && v->vcpu_info )        printk("EM: %d   ", !!vcpu_info(v, evtchn_upcall_mask));    printk("CONTEXT: %s\n", context_names[context]);    printk("rax: %016lx   rbx: %016lx   rcx: %016lx\n",           regs->rax, regs->rbx, regs->rcx);    printk("rdx: %016lx   rsi: %016lx   rdi: %016lx\n",           regs->rdx, regs->rsi, regs->rdi);    printk("rbp: %016lx   rsp: %016lx   r8:  %016lx\n",           regs->rbp, regs->rsp, regs->r8);    printk("r9:  %016lx   r10: %016lx   r11: %016lx\n",           regs->r9,  regs->r10, regs->r11);    printk("r12: %016lx   r13: %016lx   r14: %016lx\n",           regs->r12, regs->r13, regs->r14);    printk("r15: %016lx   cr0: %016lx   cr4: %016lx\n",           regs->r15, crs[0], crs[4]);    printk("cr3: %016lx   cr2: %016lx\n", 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_pv_guest;            fault_crs[2] = arch_get_cr2(v);        }        else        {            context = CTXT_hypervisor;            fault_crs[2] = read_cr2();        }        fault_crs[0] = read_cr0();        fault_crs[3] = read_cr3();        fault_crs[4] = read_cr4();        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);    }    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) )    {        u64 from, to;        rdmsrl(this_cpu(ler_msr), from);        rdmsrl(this_cpu(ler_msr) + 1, to);        printk("ler: %016lx -> %016lx\n", from, to);    }}void vcpu_show_registers(const struct vcpu *v){    const struct cpu_user_regs *regs = &v->arch.guest_context.user_regs;    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] = arch_get_cr2(v);    crs[3] = pagetable_get_paddr(guest_kernel_mode(v, regs) ?                                 v->arch.guest_table :                                 v->arch.guest_table_user);    crs[4] = v->arch.guest_context.ctrlreg[4];    _show_registers(regs, crs, CTXT_pv_guest, v);}void show_page_walk(unsigned long addr){    unsigned long pfn, mfn = read_cr3() >> PAGE_SHIFT;    l4_pgentry_t l4e, *l4t;    l3_pgentry_t l3e, *l3t;    l2_pgentry_t l2e, *l2t;    l1_pgentry_t l1e, *l1t;    printk("Pagetable walk from %016lx:\n", addr);    l4t = mfn_to_virt(mfn);    l4e = l4t[l4_table_offset(addr)];    mfn = l4e_get_pfn(l4e);    pfn = mfn_valid(mfn) ? get_gpfn_from_mfn(mfn) : INVALID_M2P_ENTRY;    printk(" L4[0x%03lx] = %"PRIpte" %016lx\n",           l4_table_offset(addr), l4e_get_intpte(l4e), pfn);    if ( !(l4e_get_flags(l4e) & _PAGE_PRESENT) )        return;    l3t = mfn_to_virt(mfn);    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" %016lx%s\n",           l3_table_offset(addr), l3e_get_intpte(l3e), pfn,           (l3e_get_flags(l3e) & _PAGE_PSE) ? " (PSE)" : "");    if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) ||         (l3e_get_flags(l3e) & _PAGE_PSE) )        return;    l2t = mfn_to_virt(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" %016lx %s\n",           l2_table_offset(addr), l2e_get_intpte(l2e), pfn,           (l2e_get_flags(l2e) & _PAGE_PSE) ? "(PSE)" : "");    if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) ||         (l2e_get_flags(l2e) & _PAGE_PSE) )        return;    l1t = mfn_to_virt(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" %016lx\n",           l1_table_offset(addr), l1e_get_intpte(l1e), pfn);}asmlinkage void double_fault(void);asmlinkage void do_double_fault(struct cpu_user_regs *regs){    unsigned int cpu, tr;    asm volatile ( "str %0" : "=r" (tr) );    cpu = ((tr >> 3) - __FIRST_TSS_ENTRY) >> 2;    watchdog_disable();    console_force_unlock();    /* Find information saved during fault and dump it to the console. */    printk("*** DOUBLE FAULT ***\n");    print_xen_info();    printk("CPU:    %d\nRIP:    %04x:[<%016lx>]",           cpu, regs->cs, regs->rip);    print_symbol(" %s", regs->rip);    printk("\nRFLAGS: %016lx\n", regs->rflags);    printk("rax: %016lx   rbx: %016lx   rcx: %016lx\n",           regs->rax, regs->rbx, regs->rcx);    printk("rdx: %016lx   rsi: %016lx   rdi: %016lx\n",           regs->rdx, regs->rsi, regs->rdi);    printk("rbp: %016lx   rsp: %016lx   r8:  %016lx\n",           regs->rbp, regs->rsp, regs->r8);    printk("r9:  %016lx   r10: %016lx   r11: %016lx\n",           regs->r9,  regs->r10, regs->r11);    printk("r12: %016lx   r13: %016lx   r14: %016lx\n",           regs->r12, regs->r13, regs->r14);    printk("r15: %016lx    cs: %016lx    ss: %016lx\n",           regs->r15, (long)regs->cs, (long)regs->ss);    show_stack_overflow(cpu, regs->rsp);    panic("DOUBLE FAULT -- system shutdown\n");}void toggle_guest_mode(struct vcpu *v){    if ( is_pv_32bit_vcpu(v) )        return;    v->arch.flags ^= TF_kernel_mode;    asm volatile ( "swapgs" );    update_cr3(v);#ifdef USER_MAPPINGS_ARE_GLOBAL    /* Don't flush user global mappings from the TLB. Don't tick TLB clock. */    asm volatile ( "mov %0, %%cr3" : : "r" (v->arch.cr3) : "memory" );#else    write_ptbase(v);#endif}unsigned long do_iret(void){    struct cpu_user_regs *regs = guest_cpu_user_regs();    struct iret_context iret_saved;    struct vcpu *v = current;    if ( unlikely(copy_from_user(&iret_saved, (void *)regs->rsp,                                 sizeof(iret_saved))) )    {        gdprintk(XENLOG_ERR, "Fault while reading IRET context from "                "guest stack\n");        goto exit_and_crash;    }    /* Returning to user mode? */    if ( (iret_saved.cs & 3) == 3 )    {        if ( unlikely(pagetable_is_null(v->arch.guest_table_user)) )        {            gdprintk(XENLOG_ERR, "Guest switching to user mode with no "                    "user page tables\n");            goto exit_and_crash;        }        toggle_guest_mode(v);    }    regs->rip    = iret_saved.rip;    regs->cs     = iret_saved.cs | 3; /* force guest privilege */    regs->rflags = (iret_saved.rflags & ~(EF_IOPL|EF_VM)) | EF_IE;    regs->rsp    = iret_saved.rsp;    regs->ss     = iret_saved.ss | 3; /* force guest privilege */    if ( !(iret_saved.flags & VGCF_in_syscall) )    {        regs->entry_vector = 0;        regs->r11 = iret_saved.r11;        regs->rcx = iret_saved.rcx;    }    /* 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) = !(iret_saved.rflags & EF_IE);    /* Saved %rax gets written back to regs->rax in entry.S. */    return iret_saved.rax; exit_and_crash:    gdprintk(XENLOG_ERR, "Fatal error\n");

⌨️ 快捷键说明

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