Example #1
0
void segfault_handler(unsigned int address, unsigned int write,
        PROCESSOR_DATA_BLOCK *hvcontext)
{
    // This is called when a program segfaults
    // If write = 1, it tried to write to the address
    PROCESSOR_DATA_BLOCK *processor = thread_get_processor_block();
    
    // Local stack context
    CONTEXT context;
    
    // If the exception was handled
    unsigned int handled = 0;
    
    // If we are first entering this handler
    unsigned int recursionCheck = 1;
    
    // Make sure only one exception gets in at a time
    if(processor->ExceptionRecursion == 0)
        lock(&program_interrupt_lock);
    else
        recursionCheck = 0;
    processor->ExceptionRecursion = 1;
    
    // Save the context
    dump_thread_context(&context);
    memcpy(context.Gpr, hvcontext->RegisterSave, 32*8);
    context.Cr = hvcontext->CRSave;
    context.Ctr = hvcontext->CTRSave;
    context.Iar = hvcontext->IARSave;
    context.Lr = hvcontext->LRSave;
    context.Msr = hvcontext->MSRSave;
    context.Xer = hvcontext->XERSave;
    
    // Adjust the context pointer
    mtsprg1(mfsprg1() - 0x200);
    
    processor->DAR = address;

    unsigned int code = write ?
        EXCEPT_CODE_SEGMENTATION_FAULT_WRITE
        : EXCEPT_CODE_SEGMENTATION_FAULT_READ;
    
    // Dispatch
    if(debugRoutine)
        handled = debugRoutine(code, &context);
    
    // Crash dump
    if(handled == 0)
        dump_thread_context_to_screen(processor, code, &context);
    
    // Restore context
    restore_thread_context(&context);
    
    processor->ExceptionRecursion = 0;
    if(recursionCheck)
        unlock(&program_interrupt_lock);
}
Example #2
0
void save_sprs(struct vcpu *v)
{
    v->arch.timebase = mftb();

    v->arch.sprg[0] = mfsprg0();
    v->arch.sprg[1] = mfsprg1();
    v->arch.sprg[2] = mfsprg2();
    v->arch.sprg[3] = mfsprg3();

    v->arch.dar = mfdar();
    v->arch.dsisr = mfdsisr();

    if (v->arch.pmu_enabled) {
        save_pmc_sprs(&(v->arch.perf_sprs));
        v->arch.perf_sprs_stored = 1;
    }

    save_cpu_sprs(v);
}