void cpu_vcpu_halt(struct vmm_vcpu * vcpu, arch_regs_t * regs) { if (vcpu->state != VMM_VCPU_STATE_HALTED) { vmm_printf("\n"); cpu_vcpu_dump_user_reg(vcpu, regs); vmm_manager_vcpu_halt(vcpu); } }
void cpu_vcpu_halt(struct vmm_vcpu *vcpu, arch_regs_t *regs) { if (!vcpu || !regs) { return; } if (vmm_manager_vcpu_get_state(vcpu) != VMM_VCPU_STATE_HALTED) { vmm_printf("\n"); cpu_vcpu_dump_user_reg(vcpu, regs); vmm_manager_vcpu_halt(vcpu); } }
static int cmd_vcpu_halt(vmm_chardev_t *cdev, int id) { int ret = VMM_EFAIL; vmm_vcpu_t *vcpu = vmm_manager_vcpu(id); if (vcpu) { if ((ret = vmm_manager_vcpu_halt(vcpu))) { vmm_cprintf(cdev, "%s: Failed to halt\n", vcpu->name); } else { vmm_cprintf(cdev, "%s: Halted\n", vcpu->name); } } else { vmm_cprintf(cdev, "Failed to find vcpu\n"); } return ret; }
void do_handle_trap(arch_regs_t *regs, unsigned long cause) { int rc = VMM_OK; bool panic = TRUE; const char *msg = "trap handling failed"; struct vmm_vcpu *vcpu; if ((cause == CAUSE_STORE_PAGE_FAULT) && !(regs->hstatus & HSTATUS_SPV) && (regs->sepc == preempt_orphan_pc)) { regs->sepc += 4; vmm_scheduler_preempt_orphan(regs); return; } vmm_scheduler_irq_enter(regs, TRUE); vcpu = vmm_scheduler_current_vcpu(); if (!vcpu || !vcpu->is_normal) { rc = VMM_EFAIL; msg = "unexpected trap"; goto done; } switch (cause) { case CAUSE_ILLEGAL_INSTRUCTION: msg = "illegal instruction fault failed"; if (regs->hstatus & HSTATUS_SPV) { rc = cpu_vcpu_illegal_insn_fault(vcpu, regs, csr_read(stval)); panic = FALSE; } else { rc = VMM_EINVALID; } break; case CAUSE_FETCH_PAGE_FAULT: case CAUSE_LOAD_PAGE_FAULT: case CAUSE_STORE_PAGE_FAULT: msg = "page fault failed"; if ((regs->hstatus & HSTATUS_SPV) && (regs->hstatus & HSTATUS_STL)) { rc = cpu_vcpu_page_fault(vcpu, regs, cause, csr_read(stval)); panic = FALSE; } else { rc = VMM_EINVALID; } break; default: rc = VMM_EFAIL; break; }; if (rc) { vmm_manager_vcpu_halt(vcpu); } done: if (rc) { do_error(vcpu, regs, cause, msg, rc, panic); } vmm_scheduler_irq_exit(regs); }