diff --git a/repos/ports/run/virtualbox_auto.inc b/repos/ports/run/virtualbox_auto.inc index 813e22488..4d757ea7d 100644 --- a/repos/ports/run/virtualbox_auto.inc +++ b/repos/ports/run/virtualbox_auto.inc @@ -216,7 +216,7 @@ append_if [expr $use_usb] config { } append_if [expr $use_usb && ![have_spec muen]] config { -} +} append_if [expr $use_usb && [have_spec muen]] config { } diff --git a/repos/ports/src/virtualbox/spec/nova/svm.h b/repos/ports/src/virtualbox/spec/nova/svm.h index 0e147f9c3..534481f61 100644 --- a/repos/ports/src/virtualbox/spec/nova/svm.h +++ b/repos/ports/src/virtualbox/spec/nova/svm.h @@ -21,9 +21,9 @@ (pCtx->REG.Attr.n.u1Granularity \ ? (pCtx->REG.u32Limit & 0xfffU) == 0xfffU \ : pCtx->REG.u32Limit <= 0xfffffU), \ - ("%u %u %#x %#x %#llx\n", pCtx->REG.Attr.n.u1Present, \ + ("Invalid Segment Attributes %u %u %#x %#x %#llx line=%u\n", pCtx->REG.Attr.n.u1Present, \ pCtx->REG.Attr.n.u1Granularity, pCtx->REG.u32Limit, \ - pCtx->REG.Attr.u, pCtx->REG.u64Base)) + pCtx->REG.Attr.u, pCtx->REG.u64Base, __LINE__)) #define GENODE_READ_SELREG(REG) \ pCtx->REG.Sel = utcb->REG.sel; \ @@ -44,6 +44,14 @@ static inline bool svm_save_state(Nova::Utcb * utcb, VM * pVM, PVMCPU pVCpu) GENODE_READ_SELREG(gs); GENODE_READ_SELREG(ss); + if ( !pCtx->cs.Attr.n.u1Granularity + && pCtx->cs.Attr.n.u1Present + && pCtx->cs.u32Limit > UINT32_C(0xfffff)) + { + Assert((pCtx->cs.u32Limit & 0xfff) == 0xfff); + pCtx->cs.Attr.n.u1Granularity = 1; + } + GENODE_SVM_ASSERT_SELREG(cs); GENODE_SVM_ASSERT_SELREG(ds); GENODE_SVM_ASSERT_SELREG(es); diff --git a/repos/ports/src/virtualbox/spec/nova/vcpu_svm.h b/repos/ports/src/virtualbox/spec/nova/vcpu_svm.h index 453e6444e..286f338cc 100644 --- a/repos/ports/src/virtualbox/spec/nova/vcpu_svm.h +++ b/repos/ports/src/virtualbox/spec/nova/vcpu_svm.h @@ -24,31 +24,14 @@ class Vcpu_handler_svm : public Vcpu_handler __attribute__((noreturn)) void _svm_default() { _default_handler(); } - __attribute__((noreturn)) void _svm_vintr() { _irq_window(); } - - __attribute__((noreturn)) void _svm_ioio() + __attribute__((noreturn)) void _svm_invalid() { - using namespace Nova; - using namespace Genode; - - Thread *myself = Thread::myself(); - Utcb *utcb = reinterpret_cast(myself->utcb()); - - if (utcb->qual[0] & 0x4) { - unsigned ctrl0 = utcb->ctrl[0]; - - Vmm::warning("invalid gueststate"); - - utcb->ctrl[0] = ctrl0; - utcb->ctrl[1] = 0; - utcb->mtd = Mtd::CTRL; - - Nova::reply(_stack_reply); - } - + Vmm::error("invalid guest state - dead ?"); _default_handler(); } + __attribute__((noreturn)) void _svm_vintr() { _irq_window(); } + template __attribute__((noreturn)) void _svm_npt() { @@ -68,8 +51,29 @@ class Vcpu_handler_svm : public Vcpu_handler /* enable VM exits for CPUID */ next_utcb.mtd = Nova::Mtd::CTRL; - next_utcb.ctrl[0] = SVM_CTRL1_INTERCEPT_CPUID; - next_utcb.ctrl[1] = 0; + next_utcb.ctrl[0] = SVM_CTRL1_INTERCEPT_INTR + | SVM_CTRL1_INTERCEPT_NMI + | SVM_CTRL1_INTERCEPT_INIT + | SVM_CTRL1_INTERCEPT_RDPMC + | SVM_CTRL1_INTERCEPT_CPUID + | SVM_CTRL1_INTERCEPT_RSM + | SVM_CTRL1_INTERCEPT_HLT + | SVM_CTRL1_INTERCEPT_INOUT_BITMAP + | SVM_CTRL1_INTERCEPT_MSR_SHADOW + | SVM_CTRL1_INTERCEPT_INVLPGA + | SVM_CTRL1_INTERCEPT_SHUTDOWN + | SVM_CTRL1_INTERCEPT_FERR_FREEZE; + + next_utcb.ctrl[1] = SVM_CTRL2_INTERCEPT_VMRUN + | SVM_CTRL2_INTERCEPT_VMMCALL + | SVM_CTRL2_INTERCEPT_VMLOAD + | SVM_CTRL2_INTERCEPT_VMSAVE + | SVM_CTRL2_INTERCEPT_STGI + | SVM_CTRL2_INTERCEPT_CLGI + | SVM_CTRL2_INTERCEPT_SKINIT + | SVM_CTRL2_INTERCEPT_WBINVD + | SVM_CTRL2_INTERCEPT_MONITOR + | SVM_CTRL2_INTERCEPT_MWAIT; void *exit_status = _start_routine(_arg); pthread_exit(exit_status); @@ -82,6 +86,12 @@ class Vcpu_handler_svm : public Vcpu_handler Vcpu_handler::_recall_handler(); } + __attribute__((noreturn)) void _svm_triple() + { + Vmm::error("triple fault - dead"); + exit(-1); + } + public: Vcpu_handler_svm(Genode::Env &env, size_t stack_size, const pthread_attr_t *attr, @@ -100,10 +110,14 @@ class Vcpu_handler_svm : public Vcpu_handler typedef Vcpu_handler_svm This; + register_handler (exc_base, Mtd::ALL | Mtd::FPU); + register_handler (exc_base, Mtd(Mtd::ALL | Mtd::FPU)); register_handler (exc_base, Mtd::ALL | Mtd::FPU); register_handler (exc_base, Mtd(Mtd::ALL | Mtd::FPU)); + &This::_svm_default> (exc_base, Mtd(Mtd::ALL | Mtd::FPU)); register_handler (exc_base, Mtd(Mtd::ALL | Mtd::FPU)); register_handler (exc_base, Mtd(Mtd::ALL | Mtd::FPU)); register_handler (exc_base, Mtd(Mtd::ALL | Mtd::FPU)); + register_handler (exc_base, Mtd(Mtd::ALL | Mtd::FPU)); + + register_handler (exc_base, Mtd(Mtd::ALL | Mtd::FPU)); start(); }