void load_sprs(struct vcpu *v) { ulong timebase_delta; mtsprg0(v->arch.sprg[0]); mtsprg1(v->arch.sprg[1]); mtsprg2(v->arch.sprg[2]); mtsprg3(v->arch.sprg[3]); mtdar(v->arch.dar); mtdsisr(v->arch.dsisr); if (v->arch.pmu_enabled) { if (v->arch.perf_sprs_stored) load_pmc_sprs(&(v->arch.perf_sprs)); else load_pmc_sprs(&perf_clear_sprs); } load_cpu_sprs(v); /* adjust the DEC value to account for cycles while not * running this OS */ timebase_delta = mftb() - v->arch.timebase; if (timebase_delta > v->arch.dec) v->arch.dec = 0; else v->arch.dec -= timebase_delta; }
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); }