summaryrefslogtreecommitdiffstats
path: root/src/VBox/VMM/Docs-RawMode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/VMM/Docs-RawMode.cpp')
-rw-r--r--src/VBox/VMM/Docs-RawMode.cpp148
1 files changed, 148 insertions, 0 deletions
diff --git a/src/VBox/VMM/Docs-RawMode.cpp b/src/VBox/VMM/Docs-RawMode.cpp
new file mode 100644
index 00000000..ed203c18
--- /dev/null
+++ b/src/VBox/VMM/Docs-RawMode.cpp
@@ -0,0 +1,148 @@
+/* $Id: Docs-RawMode.cpp $ */
+/** @file
+ * This file contains the documentation of the raw-mode execution.
+ */
+
+/*
+ * Copyright (C) 2006-2020 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+
+
+/** @page pg_raw Raw-mode Code Execution
+ *
+ * VirtualBox 0.0 thru 6.0 implemented a mode of guest code execution that
+ * allowed executing mostly raw guest code directly the host CPU but without any
+ * support from VT-x or AMD-V. It was implemented for AMD64, AMD-V and VT-x
+ * were available (former) or even specified (latter two). This mode was
+ * removed in 6.1 (code ripped out) as it was mostly unused by that point and
+ * not worth the effort of maintaining.
+ *
+ * A future VirtualBox version may reintroduce a new kind of raw-mode for
+ * emulating non-x86 architectures, making use of the host MMU to efficiently
+ * emulate the target MMU. This is just a wild idea at this point.
+ *
+ *
+ * @section sec_old_rawmode Old Raw-mode
+ *
+ * Running guest code unmodified on the host CPU is reasonably unproblematic for
+ * ring-3 code when it runs without IOPL=3. There will be some information
+ * leaks thru CPUID, a bunch of 286 area unprivileged instructions revealing
+ * privileged information (like SGDT, SIDT, SLDT, STR, SMSW), and hypervisor
+ * selectors can probably be identified using VERR, VERW and such instructions.
+ * However, it generally works fine for half friendly software when the CPUID
+ * difference between the target and host isn't too big.
+ *
+ * Kernel code can be executed on the host CPU too, however it needs to be
+ * pushed up a ring (guest ring-0 to ring-1, guest ring-1 to ring2) to let the
+ * hypervisor (VMMRC.rc) be in charge of ring-0. Ring compression causes
+ * issues when CS or SS are pushed and inspected by the guest, since the values
+ * will have bit 0 set whereas the guest expects that bit to be cleared. In
+ * addition there are problematic instructions like POPF and IRET that the guest
+ * code uses to restore/modify EFLAGS.IF state, however the CPU just silently
+ * ignores EFLAGS.IF when it isn't running in ring-0 (or with an appropriate
+ * IOPL), which causes major headache. The SIDT, SGDT, STR, SLDT and SMSW
+ * instructions also causes problems since they will return information about
+ * the hypervisor rather than the guest state and cannot be trapped.
+ *
+ * So, guest kernel code needed to be scanned (by CSAM) and problematic
+ * instructions or sequences patched or recompiled (by PATM).
+ *
+ * The raw-mode execution operates in a slightly modified guest memory context,
+ * so memory accesses can be done directly without any checking or masking. The
+ * modification was to insert the hypervisor in an unused portion of the the
+ * page tables, making it float around and require it to be relocated when the
+ * guest mapped code into the area it was occupying.
+ *
+ * The old raw-mode code was 32-bit only because its inception predates the
+ * availability of the AMD64 architecture and the promise of AMD-V and VT-x made
+ * it unnecessary to do a 64-bit version of the mode. (A long-mode port of the
+ * raw-mode execution hypvisor could in theory have been used for both 32-bit
+ * and 64-bit guest, making the relocating unnecessary for 32-bit guests,
+ * however v8086 mode does not work when the CPU is operating in long-mode made
+ * it a little less attractive.)
+ *
+ *
+ * @section sec_rawmode_v2 Raw-mode v2
+ *
+ * The vision for the reinvention of raw-mode execution is to put it inside
+ * VT-x/AMD-V and run non-native instruction sets via a recompiler.
+ *
+ * The main motivation is TLB emulation using the host MMU. An added benefit is
+ * would be that the non-native instruction sets would be add-ons put on top of
+ * the existing x86/AMD64 virtualization product and therefore not require a
+ * complete separate product build.
+ *
+ *
+ * Outline:
+ *
+ * - Plug-in based, so the target architecture specific stuff is mostly in
+ * separate modules (ring-3, ring-0 (optional) and raw-mode images).
+ *
+ * - Only 64-bit mode code (no problem since VirtualBox requires a 64-bit host
+ * since 6.0). So, not reintroducing structure alignment pain from old RC.
+ *
+ * - Map the RC-hypervisor modules as ROM, using the shadowing feature for the
+ * data sections.
+ *
+ * - Use MMIO2-like regions for all the memory that the RC-hypervisor needs,
+ * all shared with the associated host side plug-in components.
+ *
+ * - The ROM and MMIO2 regions does not directly end up in the saved state, the
+ * state is instead saved by the ring-3 architecture module.
+ *
+ * - Device access thru MMIO mappings could be done transparently thru to the
+ * x86/AMD64 core VMM. It would however be possible to reintroduce the RC
+ * side device handling, as that will not be removed in the old-RC cleanup.
+ *
+ * - Virtual memory managed by the RC-hypervisor, optionally with help of the
+ * ring-3 and/or ring-0 architecture modules.
+ *
+ * - The mapping of the RC modules and memory will probably have to runtime
+ * relocatable again, like it was in the old RC. Though initially and for
+ * 32-bit target architectures, we will probably use a fixed mapping.
+ *
+ * - Memory accesses must unfortunately be range checked before being issued,
+ * in order to prevent the guest code from accessing the hypervisor. The
+ * recompiled code must be able to run, modify state, call ROM code, update
+ * statistics and such, so we cannot use page table stuff protect the
+ * hypervisor code & data. (If long mode implement segment limits, we
+ * could've used that, but it doesn't.)
+ *
+ * - The RC-hypervisor will make hypercalls to communicate with the ring-0 and
+ * ring-3 host code.
+ *
+ * - The host side should be able to dig out the current guest state from
+ * information (think AMD64 unwinding) stored in translation blocks.
+ *
+ * - Non-atomic state updates outside TBs could be flagged so the host know
+ * how to roll the back.
+ *
+ * - SMP must be taken into account early on.
+ *
+ * - As must existing IEM-based recompiler ideas, preferrably sharing code
+ * (basically compiling IEM targetting the other architecture).
+ *
+ * The actual implementation will depend a lot on which architectures are
+ * targeted and how they can be mapped onto AMD64/x86. It is possible that
+ * there are some significan roadblocks preventing us from using the host MMU
+ * efficiently even. AMD64 is for instance rather low on virtual address space
+ * compared to several other 64-bit architectures, which means we'll generate a
+ * lot of \#GPs when the guest tries to access spaced reserved on AMD64. The
+ * proposed 5-level page tables will help with this, of course, but that need to
+ * get into silicon and into user computers for it to be really helpful.
+ *
+ * One thing that helps a lot is that we don't have to consider 32-bit x86 any
+ * more, meaning that the recompiler only need to generate 64-bit code and can
+ * assume having 15-16 GPRs at its disposal.
+ *
+ */
+