diff --git a/repos/ports/lib/mk/virtualbox5.mk b/repos/ports/lib/mk/virtualbox5.mk
deleted file mode 100644
index ad406d8b8e..0000000000
--- a/repos/ports/lib/mk/virtualbox5.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-include $(REP_DIR)/lib/mk/virtualbox5-common.inc
-
-LIBS += stdcxx
-
-SRC_CC = sup.cc sup_vmm.cc
-
-INC_DIR += $(call select_from_repositories,src/lib/libc)
-
-INC_DIR += $(VIRTUALBOX_DIR)/VBoxAPIWrap
-
-INC_DIR += $(VBOX_DIR)/Main/xml
-INC_DIR += $(VBOX_DIR)/Main/include
-INC_DIR += $(VBOX_DIR)/VMM/include
-INC_DIR += $(REP_DIR)/src/virtualbox5
-INC_DIR += $(REP_DIR)/src/virtualbox5/frontend
-
-vpath sup_vmm.cc $(REP_DIR)/src/virtualbox5/generic
-vpath sup.cc $(REP_DIR)/src/virtualbox5/generic
-
-CC_CXX_WARN_STRICT =
diff --git a/repos/ports/recipes/pkg/vbox5/README b/repos/ports/recipes/pkg/vbox5/README
deleted file mode 100644
index 65e2382a96..0000000000
--- a/repos/ports/recipes/pkg/vbox5/README
+++ /dev/null
@@ -1,2 +0,0 @@
-
- VirtualBox runtime for hosting a large VM in the Sculpt scenario
diff --git a/repos/ports/recipes/pkg/vbox5/archives b/repos/ports/recipes/pkg/vbox5/archives
deleted file mode 100644
index 275e89bc58..0000000000
--- a/repos/ports/recipes/pkg/vbox5/archives
+++ /dev/null
@@ -1,10 +0,0 @@
-_/src/vbox5
-_/src/libc
-_/src/init
-_/src/posix
-_/src/zlib
-_/src/libiconv
-_/src/libyuv
-_/src/stdcxx
-_/src/vfs
-_/src/jpeg
diff --git a/repos/ports/recipes/pkg/vbox5/hash b/repos/ports/recipes/pkg/vbox5/hash
deleted file mode 100644
index f0e236b8bc..0000000000
--- a/repos/ports/recipes/pkg/vbox5/hash
+++ /dev/null
@@ -1 +0,0 @@
-2023-08-21 464b0638d93864d8748bfa61e6472f21d6f26788
diff --git a/repos/ports/recipes/pkg/vbox5/runtime b/repos/ports/recipes/pkg/vbox5/runtime
deleted file mode 100644
index d9ef6dc178..0000000000
--- a/repos/ports/recipes/pkg/vbox5/runtime
+++ /dev/null
@@ -1,90 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/repos/ports/recipes/src/vbox5-nova/content.mk b/repos/ports/recipes/src/vbox5-nova/content.mk
index ccd65f7321..e4bb050cad 100644
--- a/repos/ports/recipes/src/vbox5-nova/content.mk
+++ b/repos/ports/recipes/src/vbox5-nova/content.mk
@@ -12,11 +12,8 @@ content: $(MIRROR_FROM_REP_DIR)
$(MIRROR_FROM_REP_DIR):
$(mirror_from_rep_dir)
-# omit virtualbox5-rem binary (12 MiB) from binary archive
-content: disable_virtualbox_rem disable_assertions
-
-disable_virtualbox_rem: $(MIRROR_FROM_REP_DIR)
- rm src/virtualbox5/target.mk
+# disable debug assertions
+content: disable_assertions
disable_assertions: $(MIRROR_FROM_REP_DIR)
rm lib/mk/virtualbox5-debug.inc
diff --git a/repos/ports/recipes/src/vbox5/content.mk b/repos/ports/recipes/src/vbox5/content.mk
deleted file mode 100644
index 4cf6d3a45a..0000000000
--- a/repos/ports/recipes/src/vbox5/content.mk
+++ /dev/null
@@ -1,84 +0,0 @@
-LIB_MK_FILES := $(notdir $(wildcard $(REP_DIR)/lib/mk/virtualbox5*))
-
-MIRROR_FROM_REP_DIR := src/virtualbox5 \
- src/virtualbox5/network.cpp \
- src/virtualbox5/include \
- include/vmm \
- $(addprefix lib/mk/,$(LIB_MK_FILES))
-
-content: $(MIRROR_FROM_REP_DIR)
-
-$(MIRROR_FROM_REP_DIR):
- $(mirror_from_rep_dir)
-
-# omit virtualbox5-rem binary (12 MiB) from binary archive
-content: disable_virtualbox_nova disable_assertions
-
-disable_virtualbox_nova: $(MIRROR_FROM_REP_DIR)
- rm src/virtualbox5/nova/target.mk
- rmdir src/virtualbox5/nova
- rm -r src/virtualbox5/spec
-
-disable_assertions: $(MIRROR_FROM_REP_DIR)
- rm lib/mk/virtualbox5-debug.inc
- touch lib/mk/virtualbox5-debug.inc
-
-PORT_DIR := $(call port_dir,$(REP_DIR)/ports/virtualbox5)
-
-MIRROR_FROM_PORT_DIR := src/app/virtualbox src/app/virtualbox_sdk \
- VBoxAPIWrap VirtualBox_stripped.xidl
-
-content: $(MIRROR_FROM_PORT_DIR)
-
-$(MIRROR_FROM_PORT_DIR):
- mkdir -p $(dir $@)
- cp -r $(PORT_DIR)/$@ $(dir $@)
-
-MIRROR_FROM_LIBPORTS := lib/mk/libc-mem.mk \
- lib/mk/libc-common.inc \
- src/lib/libc/internal/init.h \
- src/lib/libc/internal/mem_alloc.h \
- src/lib/libc/internal/monitor.h \
- src/lib/libc/internal/pthread.h \
- src/lib/libc/internal/thread_create.h \
- src/lib/libc/internal/timer.h \
- src/lib/libc/internal/types.h \
- src/lib/libc/libc_mem_alloc.cc \
- lib/import/import-qemu-usb_include.mk \
- lib/mk/qemu-usb_include.mk \
- lib/mk/qemu-usb.inc \
- lib/mk/spec/x86_32/qemu-usb.mk \
- lib/mk/spec/x86_64/qemu-usb.mk \
- include/qemu \
- src/lib/qemu-usb \
-
-content: $(MIRROR_FROM_LIBPORTS)
-
-$(MIRROR_FROM_LIBPORTS):
- mkdir -p $(dir $@)
- cp -r $(GENODE_DIR)/repos/libports/$@ $(dir $@)
-
-QEMU_USB_PORT_DIR := $(call port_dir,$(GENODE_DIR)/repos/libports/ports/qemu-usb)
-
-MIRROR_FROM_QEMU_USB_PORT_DIR := src/lib/qemu
-
-content: $(MIRROR_FROM_QEMU_USB_PORT_DIR)
-
-$(MIRROR_FROM_QEMU_USB_PORT_DIR):
- mkdir -p $(dir $@)
- cp -r $(QEMU_USB_PORT_DIR)/$@ $(dir $@)
-
-MIRROR_FROM_OS := src/drivers/ps2/scan_code_set_1.h \
- include/pointer/shape_report.h \
-
-content: $(MIRROR_FROM_OS)
-
-$(MIRROR_FROM_OS):
- mkdir -p $(dir $@)
- cp -r $(GENODE_DIR)/repos/os/$@ $(dir $@)
-
-content: LICENSE
-
-LICENSE:
- echo "GNU GPL version 2, see src/app/virtualbox/COPYING" > $@
-
diff --git a/repos/ports/recipes/src/vbox5/hash b/repos/ports/recipes/src/vbox5/hash
deleted file mode 100644
index 02b6c093b0..0000000000
--- a/repos/ports/recipes/src/vbox5/hash
+++ /dev/null
@@ -1 +0,0 @@
-2023-08-21 8bc399184344e122bbf80d7130e42fe63f91343c
diff --git a/repos/ports/recipes/src/vbox5/used_apis b/repos/ports/recipes/src/vbox5/used_apis
deleted file mode 100644
index ff57e13e44..0000000000
--- a/repos/ports/recipes/src/vbox5/used_apis
+++ /dev/null
@@ -1,23 +0,0 @@
-audio_in_session
-audio_out_session
-base
-capture_session
-framebuffer_session
-input_session
-libc
-libiconv
-nic_session
-gui_session
-os
-report_session
-rtc_session
-stdcxx
-terminal_session
-timer_session
-usb_session
-vfs
-vm_session
-nitpicker_gfx
-blit
-libyuv
-format
diff --git a/repos/ports/run/vbox5_ubuntu_16_04_32.run b/repos/ports/run/vbox5_ubuntu_16_04_32.run
index 1c9a15e0d5..2a57e0da96 100644
--- a/repos/ports/run/vbox5_ubuntu_16_04_32.run
+++ b/repos/ports/run/vbox5_ubuntu_16_04_32.run
@@ -25,7 +25,4 @@ set use_ps2 1
set use_vms 1
set use_cpu_load 1
-# use non-generic vbox5 VMM version
-set use_vbox5_nova 1
-
source ${genode_dir}/repos/ports/run/vbox_win.inc
diff --git a/repos/ports/run/vbox5_ubuntu_16_04_64.run b/repos/ports/run/vbox5_ubuntu_16_04_64.run
index b893e98f23..7baa7e8e8a 100644
--- a/repos/ports/run/vbox5_ubuntu_16_04_64.run
+++ b/repos/ports/run/vbox5_ubuntu_16_04_64.run
@@ -25,7 +25,4 @@ set use_ps2 1
set use_vms 1
set use_cpu_load 1
-# use non-generic vbox5 VMM version
-set use_vbox5_nova 1
-
source ${genode_dir}/repos/ports/run/vbox_win.inc
diff --git a/repos/ports/run/vbox5_vm_ubuntu_16_04_32.run b/repos/ports/run/vbox5_vm_ubuntu_16_04_32.run
deleted file mode 100644
index 369cad5067..0000000000
--- a/repos/ports/run/vbox5_vm_ubuntu_16_04_32.run
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# Ubuntu 16.04 32bit in VBox 5
-#
-
-assert_spec x86
-
-if {(![have_spec nova] && ![have_spec foc])} {
- puts "Platform is unsupported."
-}
-
-set flavor "ubuntu_16_04_32"
-
-set vm_ram "1280M"
-
-set use_vbox5 1
-
-set use_rumpfs 1
-# Write overlay only into ram
-set use_ram_fs 1
-# However read initial overlay from disk
-set use_overlay_from_disk 1
-
-set use_serial 1
-set use_check_result 1
-
-set use_usb [expr ![get_cmd_switch --autopilot]]
-set use_ps2 1
-
-set use_vms 1
-set use_cpu_load 1
-
-# use generic vbox5 VMM version
-set use_vbox5_nova 0
-
-source ${genode_dir}/repos/ports/run/vbox_win.inc
diff --git a/repos/ports/run/vbox5_vm_ubuntu_16_04_64.run b/repos/ports/run/vbox5_vm_ubuntu_16_04_64.run
deleted file mode 100644
index 843593253a..0000000000
--- a/repos/ports/run/vbox5_vm_ubuntu_16_04_64.run
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# Ubuntu 16.04 64bit in VBox 5
-#
-
-assert_spec x86_64
-assert_spec nova
-
-set flavor "ubuntu_16_04_64"
-set vm_ram "9460M"
-
-set use_vbox5 1
-
-set use_rumpfs 1
-# Write overlay only into ram
-set use_ram_fs 1
-# However read initial overlay from disk
-set use_overlay_from_disk 1
-
-set use_serial 1
-set use_check_result 1
-
-set use_usb [expr ![get_cmd_switch --autopilot]]
-set use_ps2 1
-
-set use_vms 1
-set use_cpu_load 1
-
-# use generic vbox5 VMM version
-set use_vbox5_nova 0
-
-source ${genode_dir}/repos/ports/run/vbox_win.inc
diff --git a/repos/ports/run/vbox5_vm_win10_64.run b/repos/ports/run/vbox5_vm_win10_64.run
deleted file mode 100644
index 27cf1baeaf..0000000000
--- a/repos/ports/run/vbox5_vm_win10_64.run
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# Windows 10 in VirtualBox 5
-#
-
-assert_spec nova
-assert_spec x86_64
-
-set flavor "win10_64_1vcpu"
-set vm_ram "8280M"
-
-set use_vbox5 1
-
-set use_rumpfs 1
-# Write overlay only into ram
-set use_ram_fs 1
-# However read initial overlay from disk
-set use_overlay_from_disk 1
-
-set use_serial 0
-set use_check_result 1
-
-set use_usb [expr ![get_cmd_switch --autopilot]]
-set use_ps2 1
-
-set use_vms 1
-set use_cpu_load 0
-
-# use generic vbox5 VMM version
-set use_vbox5_nova 0
-
-source ${genode_dir}/repos/ports/run/vbox_win.inc
diff --git a/repos/ports/run/vbox5_vm_win7_32.run b/repos/ports/run/vbox5_vm_win7_32.run
deleted file mode 100644
index ebbf6ecc2d..0000000000
--- a/repos/ports/run/vbox5_vm_win7_32.run
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# Windows 7 in VirtualBox 5
-#
-
-assert_spec x86
-assert_spec nova
-
-set flavor "win7"
-set vm_ram "1280M"
-
-set use_vbox5 1
-
-set use_rumpfs 1
-# Write overlay only into ram
-set use_ram_fs 1
-# However read initial overlay from disk
-set use_overlay_from_disk 1
-
-set use_serial 0
-set use_check_result 1
-
-set use_usb [expr ![get_cmd_switch --autopilot]]
-set use_ps2 1
-
-set use_vms 1
-set use_cpu_load 0
-
-# use generic vbox5 VMM version
-set use_vbox5_nova 0
-
-source ${genode_dir}/repos/ports/run/vbox_win.inc
diff --git a/repos/ports/run/vbox5_vm_win7_64.run b/repos/ports/run/vbox5_vm_win7_64.run
deleted file mode 100644
index 54b70a1c25..0000000000
--- a/repos/ports/run/vbox5_vm_win7_64.run
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# Windows 7 64bit in VirtualBox
-#
-
-assert_spec x86_64
-assert_spec nova
-
-set flavor "win7_64_1vcpu"
-set vm_ram "9480M"
-
-set use_vbox5 1
-
-set use_rumpfs 1
-# Write overlay only into ram
-set use_ram_fs 1
-# However read initial overlay from disk
-set use_overlay_from_disk 1
-
-set use_serial 0
-set use_check_result 1
-
-set use_usb [expr ![get_cmd_switch --autopilot]]
-set use_ps2 1
-
-set use_vms 1
-set use_cpu_load 0
-
-# use generic vbox5 VMM version
-set use_vbox5_nova 0
-
-source ${genode_dir}/repos/ports/run/vbox_win.inc
diff --git a/repos/ports/run/vbox5_win10_64.run b/repos/ports/run/vbox5_win10_64.run
index 6e3a6cf71a..7f406d41b4 100644
--- a/repos/ports/run/vbox5_win10_64.run
+++ b/repos/ports/run/vbox5_win10_64.run
@@ -25,9 +25,6 @@ set use_ps2 1
set use_vms 1
set use_cpu_load 0
-# use non-generic vbox5 VMM version
-set use_vbox5_nova 1
-
set use_webcam 1
source ${genode_dir}/repos/ports/run/vbox_win.inc
diff --git a/repos/ports/run/vbox5_win7_32.run b/repos/ports/run/vbox5_win7_32.run
index b66f5b11f4..d478f18a8c 100644
--- a/repos/ports/run/vbox5_win7_32.run
+++ b/repos/ports/run/vbox5_win7_32.run
@@ -25,7 +25,4 @@ set use_ps2 1
set use_vms 1
set use_cpu_load 0
-# use non-generic vbox5 VMM version
-set use_vbox5_nova 1
-
source ${genode_dir}/repos/ports/run/vbox_win.inc
diff --git a/repos/ports/run/vbox5_win7_64.run b/repos/ports/run/vbox5_win7_64.run
index f6f85b6214..e993df149a 100644
--- a/repos/ports/run/vbox5_win7_64.run
+++ b/repos/ports/run/vbox5_win7_64.run
@@ -25,7 +25,4 @@ set use_ps2 1
set use_vms 1
set use_cpu_load 0
-# use non-generic vbox5 VMM version
-set use_vbox5_nova 1
-
source ${genode_dir}/repos/ports/run/vbox_win.inc
diff --git a/repos/ports/run/vbox5_win7_64_multiple.run b/repos/ports/run/vbox5_win7_64_multiple.run
index 9e36342a36..c03e276cb9 100644
--- a/repos/ports/run/vbox5_win7_64_multiple.run
+++ b/repos/ports/run/vbox5_win7_64_multiple.run
@@ -37,7 +37,4 @@ set use_vms 6
set affinity_space_width 8
set use_cpu_load 0
-# use non-generic vbox5 VMM version
-set use_vbox5_nova 1
-
source ${genode_dir}/repos/ports/run/vbox_win.inc
diff --git a/repos/ports/run/vbox5_win7_64_raw.run b/repos/ports/run/vbox5_win7_64_raw.run
index 29ecf9d7af..cc288b56ec 100644
--- a/repos/ports/run/vbox5_win7_64_raw.run
+++ b/repos/ports/run/vbox5_win7_64_raw.run
@@ -24,7 +24,4 @@ set use_ps2 1
set use_vms 1
set use_cpu_load 0
-# use non-generic vbox5 VMM version
-set use_vbox5_nova 1
-
source ${genode_dir}/repos/ports/run/vbox_win.inc
diff --git a/repos/ports/run/vbox_win.inc b/repos/ports/run/vbox_win.inc
index 52de7ecde1..fe3516c32a 100644
--- a/repos/ports/run/vbox_win.inc
+++ b/repos/ports/run/vbox_win.inc
@@ -53,8 +53,7 @@ set boot_modules {
dynamic_rom
}
-set virtualbox5_binary "virtualbox5"
-if {$use_vbox5_nova} { set virtualbox5_binary "virtualbox5-nova" }
+set virtualbox5_binary "virtualbox5-nova"
set config_of_app {
@@ -83,7 +82,7 @@ set config_of_app {
Note: to get network access in the VM, the virtual network adapter
needs to be enabled in the .vbox file (disabled by default)
-->
-
+
diff --git a/repos/ports/run/virtualbox.run b/repos/ports/run/virtualbox.run
index 0ad3d5b678..9749b0ec35 100644
--- a/repos/ports/run/virtualbox.run
+++ b/repos/ports/run/virtualbox.run
@@ -1,10 +1,10 @@
+assert_spec nova
+
set use_net 0
set use_usb_qemu 0
set use_serial 1
set use_top 1
-set use_vbox5_nova 0
-
# use_gui starts two VMs
set use_gui 0
@@ -15,11 +15,7 @@ set build_components {
append build_components virtualbox5
-set virtualbox_binary "virtualbox5"
-
-if {$use_vbox5_nova} {
- set virtualbox_binary "virtualbox5-nova"
-}
+set virtualbox_binary "virtualbox5-nova"
create_boot_directory
diff --git a/repos/ports/run/vm_stress_vbox5-debian32.run b/repos/ports/run/vm_stress_vbox5-debian32.run
index 74230769d0..ba41d5d9e1 100644
--- a/repos/ports/run/vm_stress_vbox5-debian32.run
+++ b/repos/ports/run/vm_stress_vbox5-debian32.run
@@ -31,27 +31,6 @@ set match_guest_log "\[init -\> log_terminal\]"
set match_boot_string "\[init -\> vbox.*\].*Using VMX virtualization extension"
#set match_guest_down
-# use generic vbox5 VMM version
-set use_vbox5_nova 0
-set vmm_name "vbox5_gen"
-
-set use_vcpus 1
-lappend results_expected 1 3 23 79
-lappend boottime_expected 54
-source ${genode_dir}/repos/ports/run/vbox_win.inc
-source ${genode_dir}/repos/ports/run/vmm_vm_stress.inc
-kill_spawned [output_spawn_id]
-
-# set use_vcpus 2
-# lappend results_expected 2 10 42 50
-# lappend boottime_expected 21
-# source ${genode_dir}/repos/ports/run/vbox_win.inc
-# source ${genode_dir}/repos/ports/run/vmm_vm_stress.inc
-# kill_spawned [output_spawn_id]
-
-if {[have_spec nova]} {
- # use non-generic vbox5 VMM version
- set use_vbox5_nova 1
set vmm_name "vbox5_nova"
set use_vcpus 1
@@ -81,7 +60,6 @@ if {[have_spec nova]} {
source ${genode_dir}/repos/ports/run/vbox_win.inc
source ${genode_dir}/repos/ports/run/vmm_vm_stress.inc
kill_spawned [output_spawn_id]
-}
#
# Dump aggregated output of the several runs above
diff --git a/repos/ports/run/vm_stress_vbox5-debian64.run b/repos/ports/run/vm_stress_vbox5-debian64.run
index f29da65ad9..077c668cc2 100644
--- a/repos/ports/run/vm_stress_vbox5-debian64.run
+++ b/repos/ports/run/vm_stress_vbox5-debian64.run
@@ -31,27 +31,6 @@ set match_guest_log "\[init -\> log_terminal\]"
set match_boot_string "\[init -\> vbox.*\].*Using VMX virtualization extension"
#set match_guest_down
-# use generic vbox5 VMM version
-set use_vbox5_nova 0
-set vmm_name "vbox5_gen"
-
-set use_vcpus 1
-lappend results_expected 1 2 25 78
-lappend boottime_expected 24
-source ${genode_dir}/repos/ports/run/vbox_win.inc
-source ${genode_dir}/repos/ports/run/vmm_vm_stress.inc
-kill_spawned [output_spawn_id]
-
-# set use_vcpus 2
-# lappend results_expected 0 0 0 0
-# lappend boottime_expected 35
-# source ${genode_dir}/repos/ports/run/vbox_win.inc
-# source ${genode_dir}/repos/ports/run/vmm_vm_stress.inc
-# kill_spawned [output_spawn_id]
-
-if {[have_spec nova]} {
- # use non-generic vbox5 VMM version
- set use_vbox5_nova 1
set vmm_name "vbox5_nova"
set use_vcpus 1
@@ -81,7 +60,6 @@ if {[have_spec nova]} {
source ${genode_dir}/repos/ports/run/vbox_win.inc
source ${genode_dir}/repos/ports/run/vmm_vm_stress.inc
kill_spawned [output_spawn_id]
-}
#
# Dump aggregated output of the several runs above
diff --git a/repos/ports/src/virtualbox5/generic/sup.cc b/repos/ports/src/virtualbox5/generic/sup.cc
deleted file mode 100644
index b54d7548f0..0000000000
--- a/repos/ports/src/virtualbox5/generic/sup.cc
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * \brief VirtualBox SUPLib supplements
- * \author Norman Feske
- * \date 2013-08-20
- */
-
-/*
- * Copyright (C) 2013-2017 Genode Labs GmbH
- *
- * This file is distributed under the terms of the GNU General Public License
- * version 2.
- */
-
-/* Genode includes */
-#include
-#include
-
-/* Genode/Virtualbox includes */
-#include "sup.h"
-#include "vmm.h"
-
-/* VirtualBox includes */
-#include
-#include
-#include
-
-
-SUPR3DECL(SUPPAGINGMODE) SUPR3GetPagingMode(void)
-{
- return sizeof(void *) == 4 ? SUPPAGINGMODE_32_BIT : SUPPAGINGMODE_AMD64_NX;
-}
-
-
-int SUPR3Term(bool) { return VINF_SUCCESS; }
-
-
-int SUPR3HardenedLdrLoadAppPriv(const char *pszFilename, PRTLDRMOD phLdrMod,
- uint32_t fFlags, PRTERRINFO pErrInfo)
-{
- return RTLdrLoad(pszFilename, phLdrMod);
-}
-
-
-SUPR3DECL(int) SUPR3PageFreeEx(void *pvPages, size_t cPages)
-{
- Genode::log(__func__, " pvPages=", pvPages, " pages=", cPages);
- return VINF_SUCCESS;
-}
-
-
-int SUPR3QueryMicrocodeRev(uint32_t *puMicrocodeRev)
-{
- return E_FAIL;
-}
-
-uint32_t SUPSemEventMultiGetResolution(PSUPDRVSESSION)
-{
- return 100000*10; /* called by 'vmR3HaltGlobal1Init' */
-}
-
-
-int SUPSemEventCreate(PSUPDRVSESSION pSession, PSUPSEMEVENT phEvent)
-{
- return RTSemEventCreate((PRTSEMEVENT)phEvent);
-}
-
-
-int SUPSemEventClose(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent)
-{
- Assert (hEvent);
-
- return RTSemEventDestroy((RTSEMEVENT)hEvent);
-}
-
-
-int SUPSemEventSignal(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent)
-{
- Assert (hEvent);
-
- return RTSemEventSignal((RTSEMEVENT)hEvent);
-}
-
-
-int SUPSemEventWaitNoResume(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent,
- uint32_t cMillies)
-{
- Assert (hEvent);
-
- return RTSemEventWaitNoResume((RTSEMEVENT)hEvent, cMillies);
-}
-
-
-int SUPSemEventMultiCreate(PSUPDRVSESSION, PSUPSEMEVENTMULTI phEventMulti)
-{
- RTSEMEVENTMULTI sem;
-
- /*
- * Input validation.
- */
- AssertPtrReturn(phEventMulti, VERR_INVALID_POINTER);
-
- /*
- * Create the event semaphore object.
- */
- int rc = RTSemEventMultiCreate(&sem);
-
- static_assert(sizeof(sem) == sizeof(*phEventMulti), "oi");
- *phEventMulti = reinterpret_cast(sem);
- return rc;
-}
-
-
-int SUPSemEventMultiWaitNoResume(PSUPDRVSESSION, SUPSEMEVENTMULTI event,
- uint32_t ms)
-{
- RTSEMEVENTMULTI const rtevent = reinterpret_cast(event);
- return RTSemEventMultiWait(rtevent, ms);
-}
-
-int SUPSemEventMultiSignal(PSUPDRVSESSION, SUPSEMEVENTMULTI event) {
- return RTSemEventMultiSignal(reinterpret_cast(event)); }
-
-int SUPSemEventMultiReset(PSUPDRVSESSION, SUPSEMEVENTMULTI event) {
- return RTSemEventMultiReset(reinterpret_cast(event)); }
-
-int SUPSemEventMultiClose(PSUPDRVSESSION, SUPSEMEVENTMULTI event) {
- return RTSemEventMultiDestroy(reinterpret_cast(event)); }
-
-
-int SUPR3CallVMMR0(PVMR0 pVMR0, VMCPUID idCpu, unsigned uOperation,
- void *pvArg)
-{
- if (uOperation == VMMR0_DO_CALL_HYPERVISOR) {
- Genode::log(__func__, ": VMMR0_DO_CALL_HYPERVISOR - doing nothing");
- return VINF_SUCCESS;
- }
- if (uOperation == VMMR0_DO_VMMR0_TERM) {
- Genode::log(__func__, ": VMMR0_DO_VMMR0_TERM - doing nothing");
- return VINF_SUCCESS;
- }
- if (uOperation == VMMR0_DO_GVMM_DESTROY_VM) {
- Genode::log(__func__, ": VMMR0_DO_GVMM_DESTROY_VM - doing nothing");
- return VINF_SUCCESS;
- }
-
- AssertMsg(uOperation != VMMR0_DO_VMMR0_TERM &&
- uOperation != VMMR0_DO_CALL_HYPERVISOR &&
- uOperation != VMMR0_DO_GVMM_DESTROY_VM,
- ("SUPR3CallVMMR0: unhandled uOperation %d", uOperation));
- return VERR_GENERAL_FAILURE;
-}
-
-
-void genode_VMMR0_DO_GVMM_CREATE_VM(PSUPVMMR0REQHDR pReqHdr)
-{
- GVMMCREATEVMREQ &req = reinterpret_cast(*pReqHdr);
-
- size_t const cCpus = req.cCpus;
-
- /*
- * Allocate and initialize VM struct
- *
- * The VM struct is followed by the variable-sizedA array of VMCPU
- * objects. 'RT_UOFFSETOF' is used to determine the size including
- * the VMCPU array.
- *
- * VM struct must be page-aligned, which is checked at least in
- * PDMR3CritSectGetNop().
- */
- size_t const cbVM = RT_UOFFSETOF(VM, aCpus[cCpus]);
-
- static Genode::Attached_ram_dataspace vm(genode_env().ram(),
- genode_env().rm(),
- cbVM);
- Assert (vm.size() >= cbVM);
-
- VM *pVM = vm.local_addr();
- Genode::memset(pVM, 0, cbVM);
-
- /*
- * On Genode, VMMR0 and VMMR3 share a single address space. Hence, the
- * same pVM pointer is valid as pVMR0 and pVMR3.
- */
- pVM->enmVMState = VMSTATE_CREATING;
- pVM->pVMR0 = (RTHCUINTPTR)pVM;
- pVM->pVMRC = (RTGCUINTPTR)pVM;
- pVM->pSession = req.pSession;
- pVM->cbSelf = cbVM;
- pVM->cCpus = cCpus;
- pVM->uCpuExecutionCap = 100; /* expected by 'vmR3CreateU()' */
- pVM->offVMCPU = RT_UOFFSETOF(VM, aCpus);
-
- for (uint32_t i = 0; i < cCpus; i++) {
- pVM->aCpus[i].pVMR0 = pVM->pVMR0;
- pVM->aCpus[i].pVMR3 = pVM;
- pVM->aCpus[i].idHostCpu = NIL_RTCPUID;
- pVM->aCpus[i].hNativeThreadR0 = NIL_RTNATIVETHREAD;
- }
-
- pVM->aCpus[0].hNativeThreadR0 = RTThreadNativeSelf();
-
- /* out parameters of the request */
- req.pVMR0 = pVM->pVMR0;
- req.pVMR3 = pVM;
-}
-
-
-void genode_VMMR0_DO_GVMM_REGISTER_VMCPU(PVMR0 pVMR0, VMCPUID idCpu)
-{
- PVM pVM = reinterpret_cast(pVMR0);
- pVM->aCpus[idCpu].hNativeThreadR0 = RTThreadNativeSelf();
-}
-
-
-HRESULT genode_check_memory_config(ComObjPtr,
- size_t const memory_vmm)
-{
- /* Request max available memory */
- size_t const memory_available = genode_env().pd().avail_ram().value;
-
- if (memory_vmm <= memory_available)
- return S_OK;
-
- Genode::error("Available memory too low to start the VM - available: ",
- memory_available, " MB < ", memory_vmm, " MB requested");
- return E_FAIL;
-}
diff --git a/repos/ports/src/virtualbox5/generic/sup_vmm.cc b/repos/ports/src/virtualbox5/generic/sup_vmm.cc
deleted file mode 100644
index d73d2c3d93..0000000000
--- a/repos/ports/src/virtualbox5/generic/sup_vmm.cc
+++ /dev/null
@@ -1,1270 +0,0 @@
-/*
- * \brief Genode specific VirtualBox SUPLib supplements
- * \author Alexander Boettcher
- * \author Norman Feske
- * \author Christian Helmuth
- */
-
-/*
- * Copyright (C) 2006-2013 Oracle Corporation
- * Copyright (C) 2013-2021 Genode Labs GmbH
- *
- * This file is distributed under the terms of the GNU General Public License
- * version 2.
- */
-
-/* Genode includes */
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-/* Genode's VirtualBox includes */
-#include "EMInternal.h" /* enable access to em.s.* */
-#include "vmm.h"
-#include "vcpu.h"
-#include "vcpu_svm.h"
-#include "vcpu_vmx.h"
-
-/* libc memory allocator */
-#include
-
-/* Genode libc pthread binding */
-#include
-
-/* libc */
-#include
-#include /* sched_yield */
-
-#include "mm.h"
-
-/* VirtualBox includes */
-#include
-#include
-
-extern "C" void PGMUnmapMemoryGenode(void *, RTGCPHYS, ::size_t);
-extern "C" void PGMFlushVMMemory();
-
-enum { VERBOSE_PGM = false };
-
-/*
- * Tracking required to fulfill VMM allocation requests of VM memory
- */
-enum {
- CHUNKID_PAGE_START = 1,
- CHUNKID_PAGE_END = 2,
- CHUNKID_START = CHUNKID_PAGE_END + 1,
-
- ONE_PAGE_SIZE = 4096,
- PAGES_SUPERPAGE = GMM_CHUNK_SIZE / ONE_PAGE_SIZE,
- HANDY_PAGES = PAGES_SUPERPAGE * (CHUNKID_PAGE_END - CHUNKID_PAGE_START + 1),
-
- MAX_VM_MEMORY = 16ULL * 1024 * 1024 * 1024, /* 16 Gb */
- MAX_CHUNK_IDS = MAX_VM_MEMORY / GMM_CHUNK_SIZE,
-};
-
-typedef Genode::Bit_allocator Page_ids;
-typedef Genode::Bit_array Free_ids;
-
-class Chunk_ids: public Genode::Bit_allocator
-{
- public:
-
- void reserve(Genode::addr_t bit_start, size_t const num) {
- _reserve(bit_start, num); };
-};
-
-static Page_ids page_ids;
-static Chunk_ids chunk_ids;
-
-struct Region : Genode::List::Element
-{
- Genode::uint64_t vmm_local;
- Genode::uint64_t size;
- Genode::Ram_dataspace_capability cap;
-
- Region(uint64_t gp, uint64_t gs, Genode::Ram_dataspace_capability c)
- : vmm_local(gp), size(gs), cap(c) { }
-
- bool contains(Genode::uint64_t p)
- {
- return (vmm_local <= p) && (p < vmm_local + size);
- }
-};
-
-static Genode::List regions;
-
-static Genode::Allocator & heap()
-{
- static Genode::Heap heap(genode_env().ram(), genode_env().rm());
- return heap;
-}
-
-
-static Sub_rm_connection &vm_memory(Genode::uint64_t vm_size = 0)
-{
- /* memory used by the VM in any order as the VMM asks for allocations */
- static Sub_rm_connection vm_memory(genode_env(), vm_size);
-
- if (!vm_size)
- return vm_memory;
-
- using namespace Genode;
-
- /* create iterator for aligned allocation and attachment of memory */
- addr_t const vmm_local = vm_memory.local_addr(0);
- Flexpage_iterator fli(vmm_local, vm_size, 0, ~0UL, 0);
-
- /* start iteration */
- Flexpage memory = fli.page();
- while (memory.valid()) {
- addr_t const memory_size = 1UL << memory.log2_order;
- addr_t allocated = 0;
-
- addr_t alloc_size = 128 * 1024 * 1024;
- if (alloc_size > memory_size)
- alloc_size = memory_size;
-
- while (allocated < memory_size) {
- Ram_dataspace_capability ds = genode_env().ram().alloc(alloc_size);
-
- addr_t to = vm_memory.attach_rwx(ds, memory.addr + allocated - vmm_local,
- alloc_size);
- Assert(to == vm_memory.local_addr(memory.addr + allocated - vmm_local));
- allocated += alloc_size;
-
- regions.insert(new (heap()) Region(to, alloc_size, ds));
-
- if (memory_size - allocated < alloc_size)
- alloc_size = memory_size - allocated;
- }
-
- /* request next aligned memory range to be allocated and attached */
- memory = fli.page();
- }
-
- /* reserve chunkids which are special or unused */
- chunk_ids.reserve(0, CHUNKID_START);
- addr_t const unused_id = CHUNKID_START + vm_size / GMM_CHUNK_SIZE;
- addr_t const unused_count = MAX_CHUNK_IDS - unused_id - 1;
- chunk_ids.reserve(unused_id, unused_count);
-
- return vm_memory;
-}
-
-
-static Genode::Vm_connection &vm_connection(long prio = 0)
-{
- static Genode::Vm_connection vm_session(genode_env(), "VBox vCPUs", prio);
- return vm_session;
-}
-
-
-/*
- * VCPU handling
- */
-
-static Genode::List &vcpu_handler_list()
-{
- static Genode::List _inst;
- return _inst;
-}
-
-
-static Vcpu_handler *lookup_vcpu_handler(unsigned int cpu_id)
-{
- for (Vcpu_handler *vcpu_handler = vcpu_handler_list().first();
- vcpu_handler;
- vcpu_handler = vcpu_handler->next())
- if (vcpu_handler->cpu_id() == cpu_id)
- return vcpu_handler;
-
- return 0;
-}
-
-
-HRESULT genode_setup_machine(ComObjPtr machine)
-{
- ULONG memory_vbox;
- HRESULT rc = machine->COMGETTER(MemorySize)(&memory_vbox);
- if (FAILED(rc))
- return rc;
-
- /*
- * Extra memory because of:
- * - first chunkid (0) can't be used (VBox don't like chunkid 0)
- * - second chunkid (1..2) is reserved for handy pages allocation
- * - another chunkid is used additional for handy pages but as large page
- */
- size_t const vmm_memory = 1024ULL * 1024 * (memory_vbox + 16) +
- (CHUNKID_START + 1) * GMM_CHUNK_SIZE;
- HRESULT ret = genode_check_memory_config(machine, vmm_memory);
- if (ret == VINF_SUCCESS)
- vm_memory(vmm_memory);
-
- return ret;
-};
-
-
-/* Genode specific function */
-
-Genode::Xml_node platform_rom()
-{
- static Genode::Attached_rom_dataspace const platform(genode_env(),
- "platform_info");
- return platform.xml().sub_node("hardware");
-}
-
-
-void SUPR3QueryHWACCLonGenodeSupport(VM * pVM)
-{
- try {
- Genode::Xml_node const features = platform_rom().sub_node("features");
- pVM->hm.s.svm.fSupported = features.attribute_value("svm", false);
- pVM->hm.s.vmx.fSupported = features.attribute_value("vmx", false);
-
- if (pVM->hm.s.svm.fSupported || pVM->hm.s.vmx.fSupported) {
- Genode::log("Using ", pVM->hm.s.svm.fSupported ? "SVM" : "VMX",
- " virtualization extension.");
- return;
- }
- } catch (...) { /* if we get an exception let hardware support off */ }
-
- Genode::warning("No virtualization hardware acceleration available");
-}
-
-
-/* VirtualBox SUPLib interface */
-int SUPR3QueryVTxSupported(void) { return VINF_SUCCESS; }
-
-
-int SUPR3CallVMMR0Fast(PVMR0 pVMR0, unsigned uOperation, VMCPUID idCpu)
-{
- switch (uOperation) {
- case SUP_VMMR0_DO_HM_RUN:
- Vcpu_handler *vcpu_handler = lookup_vcpu_handler(idCpu);
- Assert(vcpu_handler);
- return vcpu_handler->run_hw(pVMR0);
- }
- return VERR_INTERNAL_ERROR;
-}
-
-int SUPR3PageAllocEx(::size_t cPages, uint32_t fFlags, void **ppvPages,
- PRTR0PTR pR0Ptr, PSUPPAGE paPages)
-{
- Assert(ppvPages);
- Assert(!fFlags);
-
- using Genode::Attached_ram_dataspace;
- Attached_ram_dataspace * ds = new (heap()) Attached_ram_dataspace(genode_env().ram(),
- genode_env().rm(),
- cPages * ONE_PAGE_SIZE);
-
- Genode::addr_t const vmm_local = reinterpret_cast(ds->local_addr());
-
- regions.insert(new (heap()) Region(vmm_local, cPages * ONE_PAGE_SIZE, ds->cap()));
-
- *ppvPages = ds->local_addr();
- if (pR0Ptr)
- *pR0Ptr = vmm_local;
-
- if (!paPages)
- return VINF_SUCCESS;
-
- for (unsigned iPage = 0; iPage < cPages; iPage++)
- {
- paPages[iPage].uReserved = 0;
- paPages[iPage].Phys = vmm_local + iPage * ONE_PAGE_SIZE;
- }
-
- return VINF_SUCCESS;
-}
-
-enum { MAX_TRACKING = 4 };
-static struct {
- Free_ids free;
- unsigned freed;
- unsigned chunkid;
-} track_free[MAX_TRACKING];
-
-static void partial_free_large_page(unsigned chunkid, unsigned page_id)
-{
- unsigned pos = 0;
-
- /* lookup if already exist */
- for (; pos < MAX_TRACKING; pos++)
- {
- if (track_free[pos].chunkid == chunkid)
- break;
- }
-
- /* if not exist find free place */
- if (pos >= MAX_TRACKING) {
- for (int i = 0; i < MAX_TRACKING; i++) {
- if (track_free[i].chunkid)
- continue;
-
- track_free[i].chunkid = chunkid;
- track_free[i].freed = 0;
- pos = i;
- break;
- }
-
- /* too many chunkids in use ? */
- Assert (pos < MAX_TRACKING);
- if (pos >= MAX_TRACKING)
- return;
- }
-
- try {
- /* mark as in use */
- track_free[pos].free.set(page_id, 1);
- track_free[pos].freed += 1;
-
- if (track_free[pos].freed >= 512) {
- /* slow ? optimize ? XXX */
- for (unsigned i = 0; i < 512; i++) {
- if (!track_free[pos].free.get(i, 1))
- throw 1;
- track_free[pos].free.clear(i, 1);
- }
-
- track_free[pos].chunkid = 0;
- track_free[pos].freed = 0;
-
- chunk_ids.free(chunkid);
- }
- } catch (...) {
- Genode::error(__func__," ", __LINE__, " allocation failed ", pos, ":",
- chunkid, ":", page_id);
- throw;
- }
-}
-
-int SUPR3CallVMMR0Ex(PVMR0 pVMR0, VMCPUID idCpu, unsigned uOperation,
- uint64_t u64Arg, PSUPVMMR0REQHDR pReqHdr)
-{
-
- switch (uOperation) {
-
- case VMMR0_DO_GVMM_CREATE_VM:
- {
- genode_VMMR0_DO_GVMM_CREATE_VM(pReqHdr);
-
- GVMMCREATEVMREQ &req = reinterpret_cast(*pReqHdr);
- SUPR3QueryHWACCLonGenodeSupport(reinterpret_cast(req.pVMR3));
-
- return VINF_SUCCESS;
- }
- case VMMR0_DO_GVMM_REGISTER_VMCPU:
- genode_VMMR0_DO_GVMM_REGISTER_VMCPU(pVMR0, idCpu);
- return VINF_SUCCESS;
-
- case VMMR0_DO_GVMM_SCHED_HALT:
- {
- uint64_t const u64NowGip = RTTimeNanoTS();
- uint64_t const ns_diff = u64Arg > u64NowGip ? u64Arg - u64NowGip : 0;
-
- if (!ns_diff)
- return VINF_SUCCESS;
-
- using namespace Genode;
-
- if (ns_diff > RT_NS_1SEC)
- warning(" more than 1 sec vcpu halt ", ns_diff, " ns");
-
- ::Vcpu_handler *vcpu_handler = lookup_vcpu_handler(idCpu);
- Assert(vcpu_handler);
- vcpu_handler->halt(ns_diff);
-
- return VINF_SUCCESS;
- }
-
- case VMMR0_DO_GVMM_SCHED_WAKE_UP:
- {
- Vcpu_handler *vcpu_handler = lookup_vcpu_handler(idCpu);
- Assert(vcpu_handler);
-
- vcpu_handler->wake_up();
- return VINF_SUCCESS;
- }
-
- /* called by 'vmR3HaltGlobal1Halt' */
- case VMMR0_DO_GVMM_SCHED_POLL:
- return VINF_SUCCESS;
-
- case VMMR0_DO_VMMR0_INIT:
- return VINF_SUCCESS;
-
- case VMMR0_DO_GVMM_DESTROY_VM:
- case VMMR0_DO_VMMR0_TERM:
- case VMMR0_DO_HM_SETUP_VM:
- return VINF_SUCCESS;
-
- case VMMR0_DO_HM_ENABLE:
- return VINF_SUCCESS;
-
- case VMMR0_DO_GVMM_SCHED_POKE:
- {
- PVM pVM = reinterpret_cast(pVMR0);
- Vcpu_handler *vcpu_handler = lookup_vcpu_handler(idCpu);
- Assert(vcpu_handler);
- if (vcpu_handler)
- vcpu_handler->recall(pVM);
- return VINF_SUCCESS;
- }
- case VMMR0_DO_GMM_ALLOCATE_PAGES:
- {
- /*
- * VMM is asking for some host virtual memory pages without
- * allocating the backing store actually. The backing store allocation
- * takes place via VMMR0_DO_GMM_MAP_UNMAP_CHUNK. The assignment of the
- * guest addresses is known at this point.
- */
-
- static_assert(PGM_HANDY_PAGES * ONE_PAGE_SIZE == GMM_CHUNK_SIZE,
- "Don't do that - you're going to waste tons of memory");
- Assert(pReqHdr->u32Magic == SUPVMMR0REQHDR_MAGIC);
-
- /* XXX VMM/VMMR0/GMMR0.cpp check there XXX */
-
- PGMMALLOCATEPAGESREQ req = reinterpret_cast(pReqHdr);
-
- for (unsigned i = 0; i < req->cPages; i++) {
- RTHCPHYS guest_addr = req->aPages[i].HCPhysGCPhys;
- unsigned long page_idx = 0;
- unsigned long chunk_id = 0;
-
- try {
- page_idx = page_ids.alloc();
- chunk_id = CHUNKID_PAGE_START + page_idx / PAGES_SUPERPAGE;
- } catch (...) {
- Genode::error(__func__," ", __LINE__, " allocation failed");
- throw;
- }
-
- Assert (page_idx <= GMM_PAGEID_IDX_MASK);
-
- req->aPages[i].idPage = (chunk_id << GMM_CHUNKID_SHIFT) | page_idx;
- req->aPages[i].HCPhysGCPhys = vm_memory().local_addr((chunk_id * GMM_CHUNK_SIZE) | (page_idx * ONE_PAGE_SIZE));
- Assert(vm_memory().contains(req->aPages[i].HCPhysGCPhys));
-
- #if 0
- Genode::log("cPages ", Genode::Hex(req->cPages), " "
- "chunkID=", req->aPages[i].idPage >> GMM_CHUNKID_SHIFT, " "
- "pageIDX=", req->aPages[i].idPage & GMM_PAGEID_IDX_MASK, " "
- "idPage=", Genode::Hex(req->aPages[i].idPage), " "
- "GCPhys=", Genode::Hex(guest_addr), " "
- "HCPhys=", Genode::Hex(req->aPages[i].HCPhysGCPhys), " "
- "(", Genode::Hex(chunk_id * GMM_CHUNK_SIZE), " "
- "| ", Genode::Hex(page_idx * ONE_PAGE_SIZE), ") pageidx=", page_idx, " "
- "start_vm=", vm_memory().local_addr(0));
- #endif
-
- }
-
- return VINF_SUCCESS;
- }
- case VMMR0_DO_GMM_MAP_UNMAP_CHUNK:
- {
- PGMMMAPUNMAPCHUNKREQ req = reinterpret_cast(pReqHdr);
-
- Assert(pReqHdr->u32Magic == SUPVMMR0REQHDR_MAGIC);
- Assert(req->idChunkUnmap == NIL_GMM_CHUNKID);
- Assert(req->idChunkMap != NIL_GMM_CHUNKID);
-
- Genode::addr_t local_addr_offset = (uintptr_t)req->idChunkMap << GMM_CHUNK_SHIFT;
- Genode::addr_t to = vm_memory().local_addr(local_addr_offset);
-
- req->pvR3 = reinterpret_cast(to);
-
- return VINF_SUCCESS;
- }
- case VMMR0_DO_GMM_QUERY_MEM_STATS:
- {
- PGMMMEMSTATSREQ req = reinterpret_cast(pReqHdr);
- req->cAllocPages = 0;
- req->cMaxPages = 0;
- req->cBalloonedPages = 0;
- return VINF_SUCCESS;
- }
- case VMMR0_DO_PGM_ALLOCATE_HANDY_PAGES:
- {
- /*
- * VMM is asking for some host virtual memory pages without
- * allocating the backing store actually. The backing store allocation
- * takes place via VMMR0_DO_GMM_MAP_UNMAP_CHUNK. The assignment of the
- * guest addresses to these host pages is unknown at this point.
- */
-
- PVM pVM = reinterpret_cast(pVMR0);
-
- /* based on PGMR0PhysAllocateHandyPages() in VMM/VMMR0/PGMR0.cpp - start */
- uint32_t iFirst = pVM->pgm.s.cHandyPages;
- uint32_t cPages = RT_ELEMENTS(pVM->pgm.s.aHandyPages) - iFirst;
- uint32_t cPagesToUpdate = cPages;
- uint32_t cPagesToAlloc = cPages;
- /* based on PGMR0PhysAllocateHandyPages() in VMM/VMMR0/PGMR0.cpp - end */
-
- /* based on GMMR0AllocateHandyPages in VMM/VMMR0/GMMR0.cpp - start */
- unsigned iPage = 0;
- for (; iPage < cPagesToUpdate; iPage++)
- {
- AssertMsgReturn( ( pVM->pgm.s.aHandyPages[iFirst + iPage].HCPhysGCPhys <= GMM_GCPHYS_LAST
- && !(pVM->pgm.s.aHandyPages[iFirst + iPage].HCPhysGCPhys & PAGE_OFFSET_MASK))
- || pVM->pgm.s.aHandyPages[iFirst + iPage].HCPhysGCPhys == NIL_RTHCPHYS
- || pVM->pgm.s.aHandyPages[iFirst + iPage].HCPhysGCPhys == GMM_GCPHYS_UNSHAREABLE,
- ("#%#x: %RHp\n", iFirst + iPage, pVM->pgm.s.aHandyPages[iFirst + iPage].HCPhysGCPhys),
- VERR_INVALID_PARAMETER);
- AssertMsgReturn( pVM->pgm.s.aHandyPages[iFirst + iPage].idPage <= GMM_PAGEID_LAST
- /*|| pVM->pgm.s.aHandyPages[iFirst + iPage].idPage == NIL_GMM_PAGEID*/,
- ("#%#x: %#x\n", iFirst + iPage, pVM->pgm.s.aHandyPages[iFirst + iPage].idPage), VERR_INVALID_PARAMETER);
- AssertMsgReturn( pVM->pgm.s.aHandyPages[iFirst + iPage].idPage <= GMM_PAGEID_LAST
- /*|| pVM->pgm.s.aHandyPages[iFirst + iPage].idSharedPage == NIL_GMM_PAGEID*/,
- ("#%#x: %#x\n", iFirst + iPage, pVM->pgm.s.aHandyPages[iFirst + iPage].idSharedPage), VERR_INVALID_PARAMETER);
- }
-
- for (; iPage < cPagesToAlloc; iPage++)
- {
- AssertMsgReturn(pVM->pgm.s.aHandyPages[iFirst + iPage].HCPhysGCPhys == NIL_RTHCPHYS, ("#%#x: %RHp\n", iFirst + iPage, pVM->pgm.s.aHandyPages[iFirst + iPage].HCPhysGCPhys), VERR_INVALID_PARAMETER);
- AssertMsgReturn(pVM->pgm.s.aHandyPages[iFirst + iPage].idPage == NIL_GMM_PAGEID, ("#%#x: %#x\n", iFirst + iPage, pVM->pgm.s.aHandyPages[iFirst + iPage].idPage), VERR_INVALID_PARAMETER);
- AssertMsgReturn(pVM->pgm.s.aHandyPages[iFirst + iPage].idSharedPage == NIL_GMM_PAGEID, ("#%#x: %#x\n", iFirst + iPage, pVM->pgm.s.aHandyPages[iFirst + iPage].idSharedPage), VERR_INVALID_PARAMETER);
- }
-
- Genode::uint64_t chunkid = 0;
-
- try {
- chunkid = chunk_ids.alloc();
- } catch (...) {
- Genode::error(__func__," ", __LINE__, " allocation failed");
- throw;
- }
-
- if (cPagesToAlloc != GMM_CHUNK_SIZE / ONE_PAGE_SIZE)
- Genode::log("special chunkid=", chunkid, " "
- "toupdate=", cPagesToUpdate, " "
- "toalloc=", cPagesToAlloc, " "
- "virt=", Genode::Hex(vm_memory().local_addr(chunkid << GMM_CHUNK_SHIFT)));
-
- for (unsigned i = 0; i < cPagesToUpdate; i++) {
- if (pVM->pgm.s.aHandyPages[iFirst + i].idPage != NIL_GMM_PAGEID)
- {
- pVM->pgm.s.aHandyPages[iFirst + i].idPage = NIL_GMM_PAGEID;
- pVM->pgm.s.aHandyPages[iFirst + i].HCPhysGCPhys = NIL_RTHCPHYS;
- }
-
- if (pVM->pgm.s.aHandyPages[iFirst + i].idSharedPage != NIL_GMM_PAGEID)
- AssertMsgReturn(false, ("%s %u - not implemented", __func__, __LINE__), VERR_GENERAL_FAILURE);
- }
-
- for (unsigned i = 0; i < cPagesToAlloc; i++)
- {
- Assert(pVM->pgm.s.aHandyPages[iFirst + i].HCPhysGCPhys == NIL_RTHCPHYS);
- Assert(pVM->pgm.s.aHandyPages[iFirst + i].idPage == NIL_GMM_PAGEID);
- Assert(pVM->pgm.s.aHandyPages[iFirst + i].idSharedPage == NIL_GMM_PAGEID);
- }
-
- for (unsigned i = 0; i < cPagesToUpdate; i++) {
- unsigned reverse = i; //cPagesToUpdate - 1 - i;
- Assert (pVM->pgm.s.aHandyPages[iFirst + i].HCPhysGCPhys == NIL_RTHCPHYS);
- {
- pVM->pgm.s.aHandyPages[iFirst + i].idPage = (chunkid << GMM_CHUNKID_SHIFT) | (iFirst + reverse);
- pVM->pgm.s.aHandyPages[iFirst + i].idSharedPage = NIL_GMM_PAGEID;
-
- pVM->pgm.s.aHandyPages[iFirst + i].HCPhysGCPhys = vm_memory().local_addr((chunkid << GMM_CHUNK_SHIFT) | ((iFirst + reverse) * ONE_PAGE_SIZE));
- }
- }
- /* based on GMMR0AllocateHandyPages in VMM/VMMR0/GMMR0.cpp - end */
-
- /* based on PGMR0PhysAllocateHandyPages() in VMM/VMMR0/PGMR0.cpp - start */
- pVM->pgm.s.cHandyPages = RT_ELEMENTS(pVM->pgm.s.aHandyPages);
-
- for (uint32_t i = 0; i < RT_ELEMENTS(pVM->pgm.s.aHandyPages); i++)
- {
- Assert(pVM->pgm.s.aHandyPages[i].idPage != NIL_GMM_PAGEID);
- Assert(pVM->pgm.s.aHandyPages[i].idPage <= GMM_PAGEID_LAST);
- Assert(pVM->pgm.s.aHandyPages[i].idSharedPage == NIL_GMM_PAGEID);
- Assert(pVM->pgm.s.aHandyPages[i].HCPhysGCPhys != NIL_RTHCPHYS);
- Assert(!(pVM->pgm.s.aHandyPages[i].HCPhysGCPhys & ~X86_PTE_PAE_PG_MASK));
- }
- /* based on PGMR0PhysAllocateHandyPages() in VMM/VMMR0/PGMR0.cpp - end */
-
- return VINF_SUCCESS;
- }
- case VMMR0_DO_PGM_ALLOCATE_LARGE_HANDY_PAGE:
- {
- /*
- * VMM is asking for some host large virtual memory pages without
- * allocating the backing store actually. The backing store allocation
- * takes place via VMMR0_DO_GMM_MAP_UNMAP_CHUNK. The assignment of the
- * guest addresses to these host pages is unknown at this point.
- */
-
- PVM pVM = reinterpret_cast(pVMR0);
-
- Assert(pVM);
- Assert(pVM->pgm.s.cLargeHandyPages == 0);
-
- try {
- Genode::uint64_t chunkid = chunk_ids.alloc();
-
- pVM->pgm.s.aLargeHandyPage[0].idPage = (chunkid << GMM_CHUNKID_SHIFT);
- pVM->pgm.s.aLargeHandyPage[0].HCPhysGCPhys = vm_memory().local_addr(chunkid << GMM_CHUNK_SHIFT);
-
- pVM->pgm.s.cLargeHandyPages = 1;
- } catch (...) {
- Genode::error(__func__," ", __LINE__, " allocation failed");
- throw;
- }
-
- return VINF_SUCCESS;
- }
- case VMMR0_DO_GMM_BALLOONED_PAGES:
- case VMMR0_DO_GMM_RESET_SHARED_MODULES:
- case VMMR0_DO_PGM_FLUSH_HANDY_PAGES:
- {
- PVM const pVM = reinterpret_cast(pVMR0);
- PVMCPU const pVCpu = &pVM->aCpus[idCpu];
-
- /* if not in VM shutdown - complain - bug ahead */
- if (pVCpu->em.s.enmState != EMSTATE_TERMINATING)
- Genode::error("unexpected call of type ", uOperation, ", "
- "em state=", (int)pVCpu->em.s.enmState);
-
- return VINF_SUCCESS;
- }
- case VMMR0_DO_GMM_FREE_PAGES:
- {
- if (u64Arg)
- return VERR_INVALID_PARAMETER;
-
- PVM pVM = reinterpret_cast(pVMR0);
- PGMMFREEPAGESREQ pReq = reinterpret_cast(pReqHdr);
-
- AssertPtrReturn(pVM, VERR_INVALID_POINTER);
- AssertPtrReturn(pReq, VERR_INVALID_POINTER);
- AssertMsgReturn(pReq->Hdr.cbReq >= RT_UOFFSETOF(GMMFREEPAGESREQ, aPages[0]),
- ("%#x < %#x\n", pReq->Hdr.cbReq, RT_UOFFSETOF(GMMFREEPAGESREQ, aPages[0])),
- VERR_INVALID_PARAMETER);
- AssertMsgReturn(pReq->Hdr.cbReq == RT_UOFFSETOF(GMMFREEPAGESREQ, aPages[pReq->cPages]),
- ("%#x != %#x\n", pReq->Hdr.cbReq, RT_UOFFSETOF(GMMFREEPAGESREQ, aPages[pReq->cPages])),
- VERR_INVALID_PARAMETER);
-
- uint32_t cPages = pReq->cPages;
- PGMMFREEPAGEDESC paPages = &pReq->aPages[0];
- GMMACCOUNT enmAccount = pReq->enmAccount;
-
- AssertPtrReturn(paPages, VERR_INVALID_PARAMETER);
- AssertMsgReturn(enmAccount > GMMACCOUNT_INVALID && enmAccount < GMMACCOUNT_END, ("%d\n", enmAccount), VERR_INVALID_PARAMETER);
- AssertMsgReturn(cPages > 0 && cPages < RT_BIT(32 - PAGE_SHIFT), ("%#x\n", cPages), VERR_INVALID_PARAMETER);
-
- for (unsigned iPage = 0; iPage < cPages; iPage++)
- AssertMsgReturn( paPages[iPage].idPage <= GMM_PAGEID_LAST
- /*|| paPages[iPage].idPage == NIL_GMM_PAGEID*/,
- ("#%#x: %#x\n", iPage, paPages[iPage].idPage), VERR_INVALID_PARAMETER);
-
- for (uint32_t last_chunk = ~0U, iPage = 0; iPage < cPages; iPage++)
- {
- uint32_t const idPage = paPages[iPage].idPage;
- uint32_t const page_idx = idPage & GMM_PAGEID_IDX_MASK;
- uint32_t const chunkid = idPage >> GMM_CHUNKID_SHIFT;
-
- if (last_chunk != chunkid) {
- /* revoke mapping from guest VM */
- PGMUnmapMemoryGenode(nullptr, (0UL + chunkid) << GMM_CHUNK_SHIFT, GMM_CHUNK_SIZE);
-
- last_chunk = chunkid;
- }
-
- if (CHUNKID_PAGE_START <= chunkid && chunkid <= CHUNKID_PAGE_END) {
- try {
- page_ids.free((chunkid - CHUNKID_PAGE_START) * PAGES_SUPERPAGE + page_idx);
- } catch (...) {
- Genode::error(__func__," ", __LINE__, " clearing failed");
- throw;
- }
- }
-
- partial_free_large_page(chunkid, page_idx);
-
- paPages[iPage].idPage = NIL_GMM_PAGEID;
- }
-
- return VINF_SUCCESS;
- }
- case VMMR0_DO_GMM_INITIAL_RESERVATION:
- return VINF_SUCCESS;
- case VMMR0_DO_GMM_UPDATE_RESERVATION:
- return VINF_SUCCESS;
- default:
- Genode::error("SUPR3CallVMMR0Ex: unhandled uOperation ", uOperation,
- " ", (int)VMMR0_DO_PGM_ALLOCATE_HANDY_PAGES, " ",
- (int)VMMR0_DO_GMM_QUERY_MEM_STATS);
- return VERR_GENERAL_FAILURE;
- }
-}
-
-
-/**
- * Various support stuff.
- */
-uint64_t genode_cpu_hz()
-{
- static uint64_t cpu_freq = 0;
-
- if (!cpu_freq) {
- try {
- platform_rom().with_optional_sub_node("tsc", [&] (Genode::Xml_node const &tsc) {
- cpu_freq = tsc.attribute_value("freq_khz", cpu_freq); });
- cpu_freq *= 1000ULL;
- } catch (...) { }
-
- if (cpu_freq == 0) {
- Genode::error("could not read out CPU frequency");
- Genode::sleep_forever();
- }
- }
-
- return cpu_freq;
-}
-
-
-void PGMUnmapMemoryGenode(void *, RTGCPHYS guest_phys, ::size_t size)
-{
- vm_connection().detach(guest_phys, size);
-}
-
-extern "C" void PGMFlushVMMemory()
-{
- /* XXX PGMUnmapMemoryGenode on vm_session does not flush all caps */
- PGMUnmapMemoryGenode(nullptr, 0, MAX_VM_MEMORY);
-}
-
-
-extern "C" int sched_yield(void)
-{
- static unsigned long counter = 0;
-
- if (++counter % 50000 == 0)
- Genode::warning(__func__, " called ", counter, " times");
-
- return -1;
-}
-
-
-bool create_emt_vcpu(pthread_t * thread, ::size_t stack_size,
- void *(*start_routine)(void *), void *arg,
- Genode::Cpu_connection * cpu_connection,
- Genode::Affinity::Location location,
- unsigned int cpu_id, const char * name, long prio)
-{
- Genode::Xml_node const features = platform_rom().sub_node("features");
- bool const svm = features.attribute_value("svm", false);
- bool const vmx = features.attribute_value("vmx", false);
-
- if (!svm && !vmx)
- return false;
-
- Vcpu_handler *vcpu_handler = 0;
-
- if (vmx)
- vcpu_handler = new (heap()) Vcpu_handler_vmx(genode_env(),
- stack_size,
- location,
- cpu_id,
- vm_connection(prio),
- heap());
-
- if (svm)
- vcpu_handler = new (heap()) Vcpu_handler_svm(genode_env(),
- stack_size,
- location,
- cpu_id,
- vm_connection(prio),
- heap());
-
- vcpu_handler_list().insert(vcpu_handler);
-
- Libc::pthread_create_from_session(thread, start_routine, arg,
- stack_size, name, cpu_connection, location);
-
- return true;
-}
-
-static int _map_memory(Genode::Vm_connection &vm_session,
- RTGCPHYS const GCPhys,
- RTHCPHYS const vmm_local,
- size_t const mapping_size,
- bool writeable)
-{
- for (Region *region = regions.first(); region; region = region->next())
- {
- if (!region->contains(vmm_local))
- continue;
-
- bool retry = false;
-
- do {
- Genode::addr_t const offset = vmm_local - region->vmm_local;
-
- try {
- vm_session.with_upgrade([&]() {
- vm_session.attach(region->cap, GCPhys,
- { .offset = offset,
- .size = mapping_size,
- .executable = true,
- .writeable = writeable });
- });
- } catch (Genode::Vm_session::Region_conflict) {
- /* XXX PGMUnmapMemoryGenode on vm_session does not flush caps */
- vm_session.detach(GCPhys, mapping_size);
- if (retry) {
- Genode::log("region conflict - ", Genode::Hex(GCPhys),
- " ", Genode::Hex(mapping_size), " vmm_local=",
- Genode::Hex(vmm_local), " ", region->cap,
- " region=", Genode::Hex(region->vmm_local),
- "+", Genode::Hex(region->size));
-
- size_t detach_size = mapping_size;
- while (detach_size) {
- size_t const size = 4096;
- vm_session.detach(GCPhys + (mapping_size - detach_size), size);
- detach_size -= detach_size > size ? size : detach_size;
- }
-
- return VERR_PGM_DYNMAP_FAILED;
- }
-
- if (!retry) {
- retry = true;
- continue;
- }
- }
- retry = false;
- } while (retry);
-
- return VINF_SUCCESS;
- }
- Genode::error(" no mapping ?");
- return VERR_PGM_DYNMAP_FAILED;
-}
-
-class Pgm_guard
-{
- private:
- VM &_vm;
-
- public:
- Pgm_guard(VM &vm) : _vm(vm) { pgmLock(&_vm); }
- ~Pgm_guard() { pgmUnlock(&_vm); }
-};
-
-#include "PGMInline.h"
-
-Genode::Vm_connection::Exit_config const Vcpu_handler::_exit_config { /* ... */ };
-
-int Vcpu_handler::map_memory(Genode::Vm_connection &vm_session,
- RTGCPHYS const GCPhys, RTGCUINT vbox_fault_reason)
-{
- _ept_fault_addr_type = PGMPAGETYPE_INVALID;
-
- PPGMRAMRANGE const pRam = pgmPhysGetRangeAtOrAbove(_vm, GCPhys);
- if (!pRam)
- return VERR_PGM_DYNMAP_FAILED;
-
- RTGCPHYS off = GCPhys - pRam->GCPhys;
- if (off >= pRam->cb)
- return VERR_PGM_DYNMAP_FAILED;
-
- unsigned iPage = off >> PAGE_SHIFT;
- PPGMPAGE pPage = &pRam->aPages[iPage];
-
- _ept_fault_addr_type = PGM_PAGE_GET_TYPE(pPage);
-
- /*
- * If page is not allocated (== zero page) and no MMIO or active page, allocate and map it
- * immediately. Important do not do this if A20 gate is disabled, A20 gate
- * is handled by IEM/REM in this case.
- */
- if (PGM_PAGE_IS_ZERO(pPage)
- && !PGM_PAGE_IS_ALLOCATED(pPage)
- && !PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(pPage)
- && !PGM_PAGE_IS_SPECIAL_ALIAS_MMIO(pPage)
- && PGM_A20_IS_ENABLED(_vcpu))
- {
- Pgm_guard guard(*_vm);
- pgmPhysPageMakeWritable(_vm, pPage, GCPhys);
- }
-
- if (PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(pPage) ||
- PGM_PAGE_IS_SPECIAL_ALIAS_MMIO(pPage) ||
- PGM_PAGE_IS_ZERO(pPage)) {
-
- if (PGM_PAGE_GET_TYPE(pPage) != PGMPAGETYPE_MMIO &&
- !PGM_PAGE_IS_ZERO(pPage)) {
-
- Genode::log(__LINE__, " GCPhys=", Genode::Hex(GCPhys), " ",
- PGM_PAGE_HAS_ACTIVE_ALL_HANDLERS(pPage), " ",
- PGM_PAGE_IS_SPECIAL_ALIAS_MMIO(pPage), " ",
- PGM_PAGE_IS_ZERO(pPage), " "
- " vbox_fault_reason=", Genode::Hex(vbox_fault_reason));
- Genode::log(__LINE__, " GCPhys=", Genode::Hex(GCPhys), " "
- "host=", Genode::Hex(PGM_PAGE_GET_HCPHYS(pPage)), " "
- "type=", Genode::Hex(PGM_PAGE_GET_TYPE(pPage)), " "
- "writeable=true "
- "state=", Genode::Hex(PGM_PAGE_GET_STATE(pPage)));
- }
- return VERR_PGM_DYNMAP_FAILED;
- }
-
- if (!PGM_PAGE_IS_ALLOCATED(pPage))
- Genode::log("unknown page state ", Genode::Hex(PGM_PAGE_GET_STATE(pPage)),
- " GCPhys=", Genode::Hex(GCPhys));
- Assert(PGM_PAGE_IS_ALLOCATED(pPage));
-
- if (PGM_PAGE_GET_TYPE(pPage) != PGMPAGETYPE_RAM &&
- PGM_PAGE_GET_TYPE(pPage) != PGMPAGETYPE_MMIO2 &&
- PGM_PAGE_GET_TYPE(pPage) != PGMPAGETYPE_ROM)
- {
- if (VERBOSE_PGM)
- Genode::log(__LINE__, " GCPhys=", Genode::Hex(GCPhys), " "
- "vbox_fault_reason=", Genode::Hex(vbox_fault_reason), " "
- "host=", Genode::Hex(PGM_PAGE_GET_HCPHYS(pPage)), " "
- "type=", Genode::Hex(PGM_PAGE_GET_TYPE(pPage)), " "
- "state=", Genode::Hex(PGM_PAGE_GET_STATE(pPage)));
- return VERR_PGM_DYNMAP_FAILED;
- }
-
- Assert(!PGM_PAGE_IS_ZERO(pPage));
-
- /* write fault on a ROM region */
- if (PGM_PAGE_GET_TYPE(pPage) == PGMPAGETYPE_ROM &&
- vbox_fault_reason & VMX_EXIT_QUALIFICATION_EPT_DATA_WRITE) {
- Genode::warning(__func__, " - write fault on ROM region!? gp=",
- Genode::Hex(GCPhys));
- return VERR_PGM_DYNMAP_FAILED;
- }
-
- /* nothing should be mapped - otherwise we get endless overmap loops */
- Assert(!(vbox_fault_reason & VMX_EXIT_QUALIFICATION_EPT_ENTRY_PRESENT));
-
- bool const writeable = PGM_PAGE_GET_TYPE(pPage) != PGMPAGETYPE_ROM;
-
- PPGMPHYSHANDLER handler = pgmHandlerPhysicalLookup(_vm, GCPhys);
-
- if (VERBOSE_PGM && PGM_PAGE_GET_TYPE(pPage) == PGMPAGETYPE_MMIO2 &&
- !handler)
- Genode::log(__LINE__, " GCPhys=", Genode::Hex(GCPhys), " ",
- "type=", Genode::Hex(PGM_PAGE_GET_TYPE(pPage)), " "
- "state=", Genode::Hex(PGM_PAGE_GET_STATE(pPage)), " "
- "- MMIO2 w/o handler");
-
- if (PGM_PAGE_GET_TYPE(pPage) == PGMPAGETYPE_MMIO2 && handler) {
- PFNPGMPHYSHANDLER pfnHandler = PGMPHYSHANDLER_GET_TYPE(_vm, handler)->CTX_SUFF(pfnHandler);
- if (!pfnHandler) {
- Genode::log(__LINE__, " GCPhys=", Genode::Hex(GCPhys), " "
- "type=", Genode::Hex(PGM_PAGE_GET_TYPE(pPage)));
- return VERR_PGM_DYNMAP_FAILED;
- }
- void *pvUser = handler->CTX_SUFF(pvUser);
- if (!pvUser) {
- Genode::log(__LINE__, " GCPhys=", Genode::Hex(GCPhys), " "
- "type=", Genode::Hex(PGM_PAGE_GET_TYPE(pPage)));
- return VERR_PGM_DYNMAP_FAILED;
- }
-
- PGMACCESSTYPE access_type = (vbox_fault_reason & VMX_EXIT_QUALIFICATION_EPT_DATA_WRITE) ? PGMACCESSTYPE_WRITE : PGMACCESSTYPE_READ;
-
- VBOXSTRICTRC rcStrict = pfnHandler(_vm, _vcpu, GCPhys, nullptr, nullptr, 0, access_type, PGMACCESSORIGIN_HM, pvUser);
- if (rcStrict != VINF_PGM_HANDLER_DO_DEFAULT) {
- Genode::log(__LINE__, " nodefault GCPhys=", Genode::Hex(GCPhys), " "
- "type=", Genode::Hex(PGM_PAGE_GET_TYPE(pPage)), " "
- "pfnHandler=", pfnHandler);
- return VERR_PGM_DYNMAP_FAILED;
- }
- }
-
-/*
- if (VERBOSE_PGM)
- Genode::log(Genode::Hex(PGM_PAGE_GET_HCPHYS(pPage)),
- "->", Genode::Hex(GCPhys),
- " type=", PGM_PAGE_GET_TYPE(pPage),
- " state=", PGM_PAGE_GET_STATE(pPage),
- " pde_type=", PGM_PAGE_GET_PDE_TYPE(pPage),
- PGM_PAGE_GET_PDE_TYPE(pPage) == PGM_PAGE_PDE_TYPE_PDE ? "(is pde)" : "(not pde)",
- " iPage=", iPage,
- " range_start=", Genode::Hex(pRam->GCPhys),
- " range_size=", Genode::Hex(pRam->cb),
- " pages=", pRam->cb >> PAGE_SHIFT
- );
-*/
-
- if (PGM_PAGE_GET_PDE_TYPE(pPage) != PGM_PAGE_PDE_TYPE_PDE)
- return _map_memory(vm_session, GCPhys, PGM_PAGE_GET_HCPHYS(pPage), 4096, writeable); /* one page mapping */
-
- Genode::addr_t const superpage_log2 = 21;
- Genode::addr_t const max_pages = pRam->cb >> PAGE_SHIFT;
- Genode::addr_t const superpage_pages = (1UL << superpage_log2) / 4096;
- Genode::addr_t const mask = (1UL << superpage_log2) - 1;
- Genode::addr_t const super_gcphys = GCPhys & ~mask;
-
- RTGCPHYS max_off = super_gcphys - pRam->GCPhys;
- if (max_off > pRam->cb)
- return _map_memory(vm_session, GCPhys, PGM_PAGE_GET_HCPHYS(pPage), 4096, writeable); /* one page mapping */
-
- Genode::addr_t const super_hcphys = PGM_PAGE_GET_HCPHYS(pPage) & ~mask;
-
- unsigned const i_s = max_off >> PAGE_SHIFT;
-
- if (i_s + superpage_pages > max_pages)
- return _map_memory(vm_session, GCPhys, PGM_PAGE_GET_HCPHYS(pPage), 4096, writeable); /* one page mapping */
-
- if (VERBOSE_PGM)
- Genode::log(Genode::Hex(PGM_PAGE_GET_HCPHYS(pPage)), "->",
- Genode::Hex(GCPhys), " - iPage ", iPage, " [",
- i_s, ",", i_s + superpage_pages, ")", " "
- "range_size=", Genode::Hex(pRam->cb));
-
- /* paranoia sanity checks */
- for (Genode::addr_t i = i_s; i < i_s + superpage_pages; i++) {
- PPGMPAGE page = &pRam->aPages[i];
-
- Genode::addr_t const gcpage = pRam->GCPhys + (i << PAGE_SHIFT);
-
- if (!(super_hcphys == (PGM_PAGE_GET_HCPHYS(page) & ~mask)) ||
- !(super_gcphys == (gcpage & ~mask)) ||
- !(PGM_PAGE_GET_PDE_TYPE(page) == PGM_PAGE_PDE_TYPE_PDE) ||
- !(PGM_PAGE_GET_TYPE(page) == PGM_PAGE_GET_TYPE(pPage)) ||
- !(PGM_PAGE_GET_STATE(page) == PGM_PAGE_GET_STATE(pPage)))
- {
- if (VERBOSE_PGM)
- Genode::error(Genode::Hex(PGM_PAGE_GET_HCPHYS(pPage)), "->",
- Genode::Hex(GCPhys), " - iPage ", iPage, " i ", i, " [",
- i_s, ",", i_s + superpage_pages, ")", " "
- "range_size=", Genode::Hex(pRam->cb), " "
- "super_hcphys=", Genode::Hex(super_hcphys), "?=", Genode::Hex((PGM_PAGE_GET_HCPHYS(page) & ~mask)), " "
- "super_gcphys=", Genode::Hex(super_gcphys), "?=", Genode::Hex((gcpage & ~mask)), " ",
- (int)(PGM_PAGE_GET_PDE_TYPE(page)), "?=", (int)PGM_PAGE_PDE_TYPE_PDE, " ",
- (int)(PGM_PAGE_GET_TYPE(page)), "?=", (int)PGM_PAGE_GET_TYPE(pPage), " ",
- (int)(PGM_PAGE_GET_STATE(page)), "?=", (int)PGM_PAGE_GET_STATE(pPage));
- return _map_memory(vm_session, GCPhys, PGM_PAGE_GET_HCPHYS(pPage), 4096, writeable); /* one page mapping */
- }
- }
-
- /* XXX revoke of old mappings required ? */
- /* super page mapping */
- return _map_memory(vm_session, super_gcphys, super_hcphys, 1UL << superpage_log2, writeable);
-}
-
-
-Genode::uint64_t * Vcpu_handler::pdpte_map(VM *pVM, RTGCPHYS cr3)
-{
- Pgm_guard guard(*_vm);
-
- PPGMRAMRANGE pRam = pgmPhysGetRangeAtOrAbove(pVM, cr3);
- Assert (pRam);
-
- RTGCPHYS off = cr3 - pRam->GCPhys;
- Assert (off < pRam->cb);
-
- unsigned iPage = off >> PAGE_SHIFT;
- PPGMPAGE pPage = &pRam->aPages[iPage];
-
-/*
- if (VERBOSE_PGM)
- Genode::log(__LINE__, " gcphys=", Genode::Hex(cr3),
- " host=", Genode::Hex(PGM_PAGE_GET_HCPHYS(pPage)),
- " type=", Genode::Hex(PGM_PAGE_GET_TYPE(pPage)),
- " state=",Genode::Hex(PGM_PAGE_GET_STATE(pPage)));
-*/
-
- Genode::uint64_t *pdpte = reinterpret_cast(PGM_PAGE_GET_HCPHYS(pPage) + (cr3 & PAGE_OFFSET_MASK));
-
- Assert(pdpte != 0);
-
- return pdpte;
-}
-
-static PFNRTTIMER rttimer_func = nullptr;
-static void * rttimer_obj = nullptr;
-
-enum {
- UPDATE_HZ = 1000,
- UPDATE_US = 1000 * 1000 / UPDATE_HZ,
- UPDATE_NS = UPDATE_US * 1000,
-};
-
-
-PSUPGLOBALINFOPAGE g_pSUPGlobalInfoPage;
-
-
-class Periodic_gip
-{
- private :
-
- void update()
- {
- /**
- * We're using rdtsc here since timer_session->elapsed_ms produces
- * instable results when the timer service is using the Genode PIC
- * driver.
- */
-
- Genode::uint64_t tsc_current = Genode::Trace::timestamp();
-
- /*
- * Convert tsc to nanoseconds.
- *
- * There is no 'uint128_t' type on x86_32, so we use the 128-bit type
- * and functions provided by VirtualBox.
- *
- * nanots128 = tsc_current * 1000*1000*1000 / genode_cpu_hz()
- *
- */
-
- RTUINT128U nanots128;
- RTUInt128AssignU64(&nanots128, tsc_current);
-
- RTUINT128U multiplier;
- RTUInt128AssignU32(&multiplier, 1000*1000*1000);
- RTUInt128AssignMul(&nanots128, &multiplier);
-
- RTUINT128U divisor;
- RTUInt128AssignU64(&divisor, genode_cpu_hz());
- RTUInt128AssignDiv(&nanots128, &divisor);
-
- SUPGIPCPU *cpu = &g_pSUPGlobalInfoPage->aCPUs[0];
-
- /*
- * Transaction id must be incremented before and after update,
- * read struct SUPGIPCPU description for more details.
- */
- ASMAtomicIncU32(&cpu->u32TransactionId);
-
- cpu->u64TSC = tsc_current;
- cpu->u64NanoTS = nanots128.s.Lo;
-
- /*
- * Transaction id must be incremented before and after update,
- * read struct SUPGIPCPU description for more details.
- */
- ASMAtomicIncU32(&cpu->u32TransactionId);
-
- /* call the timer function of the RTTimerCreate call */
- if (rttimer_func) {
- Libc::with_libc([&] () {
- rttimer_func(nullptr, rttimer_obj, 0); });
- }
- }
-
- public:
-
- Timer::Connection _timer;
- Genode::Signal_handler _timer_handler;
-
- Periodic_gip(Genode::Env &env)
- :
- _timer(env),
- _timer_handler(env.ep(), *this, &Periodic_gip::update)
- {
- _timer.sigh(_timer_handler);
- _timer.trigger_periodic(UPDATE_US);
- }
-};
-
-
-struct Attached_gip : Genode::Attached_ram_dataspace
-{
- Attached_gip()
- : Attached_ram_dataspace(genode_env().ram(), genode_env().rm(), PAGE_SIZE)
- {
- g_pSUPGlobalInfoPage = local_addr();
-
- /* checked by TMR3Init */
- g_pSUPGlobalInfoPage->u32Version = SUPGLOBALINFOPAGE_VERSION;
- g_pSUPGlobalInfoPage->u32Magic = SUPGLOBALINFOPAGE_MAGIC;
- g_pSUPGlobalInfoPage->u32Mode = SUPGIPMODE_SYNC_TSC;
- g_pSUPGlobalInfoPage->cCpus = 1;
- g_pSUPGlobalInfoPage->cPages = 1;
- g_pSUPGlobalInfoPage->u32UpdateHz = UPDATE_HZ;
- g_pSUPGlobalInfoPage->u32UpdateIntervalNS = UPDATE_NS;
- g_pSUPGlobalInfoPage->cOnlineCpus = 0;
- g_pSUPGlobalInfoPage->cPresentCpus = 0;
- g_pSUPGlobalInfoPage->cPossibleCpus = 0;
- g_pSUPGlobalInfoPage->idCpuMax = 0;
- g_pSUPGlobalInfoPage->u64CpuHz = genode_cpu_hz();
- /* evaluated by rtTimeNanoTSInternalRediscover in Runtime/common/time/timesup.cpp */
- g_pSUPGlobalInfoPage->fGetGipCpu = SUPGIPGETCPU_APIC_ID;
-
- SUPGIPCPU *cpu = &g_pSUPGlobalInfoPage->aCPUs[0];
-
- cpu->u32TransactionId = 0;
- cpu->u32UpdateIntervalTSC = genode_cpu_hz() / UPDATE_HZ;
- cpu->u64NanoTS = 0ULL;
- cpu->u64TSC = 0ULL;
- cpu->u64CpuHz = genode_cpu_hz();
- cpu->cErrors = 0;
- cpu->iTSCHistoryHead = 0;
- cpu->u32PrevUpdateIntervalNS = UPDATE_NS;
- cpu->enmState = SUPGIPCPUSTATE_ONLINE;
- cpu->idCpu = 0;
- cpu->iCpuSet = 0;
- cpu->idApic = 0;
-
- /* schedule periodic call of GIP update function */
- static Periodic_gip periodic_gip(genode_env());
- }
-};
-
-
-int RTTimerCreate(PRTTIMER *pptimer, unsigned ms, PFNRTTIMER func, void *obj)
-{
- if (pptimer)
- *pptimer = NULL;
-
- /* used solely at one place in TM.cpp */
- Assert(!rttimer_func);
-
- /*
- * Ignore (10) ms which is too high for audio. Instead the callback
- * handler will run at UPDATE_HZ rate.
- */
- rttimer_func = func;
- rttimer_obj = obj;
-
- return VINF_SUCCESS;
-}
-
-
-int RTTimerDestroy(PRTTIMER)
-{
- rttimer_obj = nullptr;
- rttimer_func = nullptr;
- return VINF_SUCCESS;
-}
-
-
-int SUPR3Init(PSUPDRVSESSION *ppSession)
-{
- static Attached_gip gip;
-
- return VINF_SUCCESS;
-}
-
-int SUPR3GipGetPhys(PRTHCPHYS pHCPhys)
-{
- /*
- * Return VMM-local address as physical address. This address is
- * then fed to MMR3HyperMapHCPhys. (TMR3Init)
- */
- *pHCPhys = (RTHCPHYS)g_pSUPGlobalInfoPage;
-
- return VINF_SUCCESS;
-}
diff --git a/repos/ports/src/virtualbox5/svm.h b/repos/ports/src/virtualbox5/svm.h
deleted file mode 100644
index a9813df069..0000000000
--- a/repos/ports/src/virtualbox5/svm.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * \brief Genode specific VirtualBox SUPLib supplements
- * \author Norman Feske
- * \author Alexander Boettcher
- * \author Christian Helmuth
- */
-
-/*
- * Copyright (C) 2013-2021 Genode Labs GmbH
- *
- * This file is distributed under the terms of the GNU General Public License
- * version 2.
- */
-
-#ifndef _VIRTUALBOX__SVM_H_
-#define _VIRTUALBOX__SVM_H_
-
-/* based on HWSVMR0.h - adjusted to Genode */
-
-#define GENODE_SVM_ASSERT_SELREG(REG) \
- AssertMsg(!pCtx->REG.Attr.n.u1Present || \
- (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, \
- pCtx->REG.Attr.n.u1Granularity, pCtx->REG.u32Limit, \
- pCtx->REG.Attr.u, pCtx->REG.u64Base))
-
-#define GENODE_READ_SELREG(REG) \
- pCtx->REG.Sel = state->REG.value().sel; \
- pCtx->REG.ValidSel = state->REG.value().sel; \
- pCtx->REG.fFlags = CPUMSELREG_FLAGS_VALID; \
- pCtx->REG.u32Limit = state->REG.value().limit; \
- pCtx->REG.u64Base = state->REG.value().base; \
- pCtx->REG.Attr.u = sel_ar_conv_from_genode(state->REG.value().ar)
-
-static inline bool svm_save_state(Genode::Vcpu_state * state, VM * pVM, PVMCPU pVCpu)
-{
- PCPUMCTX pCtx = CPUMQueryGuestCtxPtr(pVCpu);
-
- GENODE_READ_SELREG(cs);
- GENODE_READ_SELREG(ds);
- GENODE_READ_SELREG(es);
- GENODE_READ_SELREG(fs);
- 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);
- GENODE_SVM_ASSERT_SELREG(fs);
- GENODE_SVM_ASSERT_SELREG(gs);
- GENODE_SVM_ASSERT_SELREG(ss);
-
- GENODE_READ_SELREG(ldtr);
- GENODE_READ_SELREG(tr);
-
- CPUMSetGuestEFER(pVCpu, CPUMGetGuestEFER(pVCpu) & ~uint64_t(MSR_K6_EFER_SVME));
-
- return true;
-}
-
-#undef GENODE_ASSERT_SELREG
-#undef GENODE_READ_SELREG
-
-
-
-
-#define GENODE_WRITE_SELREG(REG) \
- Assert(pCtx->REG.fFlags & CPUMSELREG_FLAGS_VALID); \
- Assert(pCtx->REG.ValidSel == pCtx->REG.Sel); \
- state->REG.charge(Segment { .sel = pCtx->REG.Sel, \
- .ar = sel_ar_conv_to_genode(pCtx->REG.Attr.u), \
- .limit = pCtx->REG.u32Limit, \
- .base = pCtx->REG.u64Base });
-
-static inline bool svm_load_state(Genode::Vcpu_state * state, VM * pVM, PVMCPU pVCpu)
-{
- typedef Genode::Vcpu_state::Segment Segment;
-
- PCPUMCTX pCtx = CPUMQueryGuestCtxPtr(pVCpu);
-
- state->efer.charge(state->efer.value() | MSR_K6_EFER_SVME);
-
- GENODE_WRITE_SELREG(es);
- GENODE_WRITE_SELREG(ds);
-
- GENODE_WRITE_SELREG(fs);
- GENODE_WRITE_SELREG(gs);
-
- GENODE_WRITE_SELREG(cs);
- GENODE_WRITE_SELREG(ss);
-
- GENODE_WRITE_SELREG(ldtr);
- GENODE_WRITE_SELREG(tr);
-
- return true;
-}
-
-#undef GENODE_WRITE_SELREG
-
-#endif /* _VIRTUALBOX__SVM_H_ */
diff --git a/repos/ports/src/virtualbox5/target.mk b/repos/ports/src/virtualbox5/target.mk
deleted file mode 100644
index f7bd54b51f..0000000000
--- a/repos/ports/src/virtualbox5/target.mk
+++ /dev/null
@@ -1,11 +0,0 @@
-TARGET = virtualbox5
-
-include $(REP_DIR)/src/virtualbox5/target.inc
-
-LIBS += virtualbox5
-LIBS += blit
-
-vpath frontend/% $(REP_DIR)/src/virtualbox5/
-vpath %.cc $(REP_DIR)/src/virtualbox5/
-
-CC_CXX_WARN_STRICT =
diff --git a/repos/ports/src/virtualbox5/vcpu.h b/repos/ports/src/virtualbox5/vcpu.h
deleted file mode 100644
index 7032a742ce..0000000000
--- a/repos/ports/src/virtualbox5/vcpu.h
+++ /dev/null
@@ -1,862 +0,0 @@
-/*
- * \brief Genode VirtualBox SUPLib supplements
- * \author Alexander Boettcher
- * \author Norman Feske
- * \author Christian Helmuth
- */
-
-/*
- * Copyright (C) 2013-2021 Genode Labs GmbH
- *
- * This file is distributed under the terms of the GNU General Public License
- * version 2.
- */
-
-#ifndef _VIRTUALBOX__VCPU_H_
-#define _VIRTUALBOX__VCPU_H_
-
-/* Genode includes */
-#include
-#include
-#include
-#include
-#include
-
-/* VirtualBox includes */
-#include "PGMInternal.h" /* enable access to pgm.s.* */
-
-#include "HMInternal.h" /* enable access to hm.s.* */
-#include "CPUMInternal.h" /* enable access to cpum.s.* */
-
-#include
-#include
-#include
-
-#include
-
-#include
-
-/* Genode's VirtualBox includes */
-#include "sup.h"
-
-/* Genode libc pthread binding */
-#include
-
-#include
-
-/*
- * VirtualBox stores segment attributes in Intel format using a 32-bit
- * value. Genode represents the attributes in packed format using a 16-bit
- * value.
- */
-static inline Genode::uint16_t sel_ar_conv_to_genode(Genode::uint32_t v)
-{
- return (v & 0xff) | ((v & 0x1f000) >> 4);
-}
-
-
-static inline Genode::uint32_t sel_ar_conv_from_genode(Genode::uint16_t v)
-{
- return (v & 0xff) | (((uint32_t )v << 4) & 0x1f000);
-}
-
-class Vcpu_handler : public Genode::List::Element
-{
- protected:
-
- static Genode::Vm_connection::Exit_config const _exit_config;
-
- Genode::Entrypoint _ep;
- Genode::Blockade _blockade_emt { };
- Genode::Semaphore _sem_handler;
- Genode::Vcpu_state *_state { nullptr };
-
- pthread_cond_t _cond_wait;
- pthread_mutex_t _mutex;
-
-
- /* information used for NPT/EPT handling */
- Genode::addr_t npt_ept_exit_addr { 0 };
- RTGCUINT npt_ept_errorcode { 0 };
- bool npt_ept_unmap { false };
-
- /* state machine between EMT and EP thread of a vCPU */
- enum { RUNNING, PAUSED, IRQ_WIN, NPT_EPT } _vm_state { PAUSED };
- enum { PAUSE_EXIT, RUN } _next_state { RUN };
-
- private:
-
- bool _irq_win = false;
-
- unsigned const _cpu_id;
- PVM _vm { nullptr };
- PVMCPU _vcpu { nullptr };
-
- unsigned int _last_inj_info = 0;
- unsigned int _last_inj_error = 0;
-
- enum {
- REQ_IRQWIN_EXIT = 0x1000U,
- IRQ_INJ_VALID_MASK = 0x80000000UL,
- IRQ_INJ_NONE = 0U,
-
- /*
- * Intel® 64 and IA-32 Architectures Software Developer’s Manual
- * Volume 3C, Chapter 24.4.2.
- * May 2012
- */
- BLOCKING_BY_STI = 1U << 0,
- BLOCKING_BY_MOV_SS = 1U << 1,
- ACTIVITY_STATE_ACTIVE = 0U,
- INTERRUPT_STATE_NONE = 0U,
- };
-
- timespec add_timespec_ns(timespec a, uint64_t ns) const
- {
- enum { NSEC_PER_SEC = 1'000'000'000ull };
-
- long sec = a.tv_sec;
-
- while (a.tv_nsec >= NSEC_PER_SEC) {
- a.tv_nsec -= NSEC_PER_SEC;
- sec++;
- }
- while (ns >= NSEC_PER_SEC) {
- ns -= NSEC_PER_SEC;
- sec++;
- }
-
- long nsec = a.tv_nsec + ns;
- while (nsec >= NSEC_PER_SEC) {
- nsec -= NSEC_PER_SEC;
- sec++;
- }
- return timespec { sec, nsec };
- }
-
- protected:
-
- int map_memory(Genode::Vm_connection &vm_session,
- RTGCPHYS GCPhys, RTGCUINT vbox_fault_reason);
-
- Genode::addr_t _vm_exits = 0;
- Genode::addr_t _recall_skip = 0;
- Genode::addr_t _recall_req = 0;
- Genode::addr_t _recall_inv = 0;
- Genode::addr_t _recall_drop = 0;
- Genode::addr_t _irq_request = 0;
- Genode::addr_t _irq_inject = 0;
- Genode::addr_t _irq_drop = 0;
-
- struct {
- unsigned ctrl[2];
- } next_utcb;
-
- unsigned _ept_fault_addr_type;
-
- Genode::uint64_t * pdpte_map(VM *pVM, RTGCPHYS cr3);
-
- void switch_to_hw(PCPUMCTX pCtx)
- {
- using Genode::Vcpu_state;
-
- again:
-
- /* write FPU state */
- AssertCompile(sizeof(Vcpu_state::Fpu::State) >= sizeof(X86FXSTATE));
- _state->fpu.charge([&] (Vcpu_state::Fpu::State &fpu) {
- ::memcpy(&fpu, pCtx->pXStateR3, sizeof(X86FXSTATE));
- });
-
- Assert(_vm_state == IRQ_WIN || _vm_state == PAUSED || _vm_state == NPT_EPT);
- Assert(_next_state == PAUSE_EXIT || _next_state == RUN);
-
- /* wake up vcpu ep handler */
- _sem_handler.up();
-
- /* wait for next exit */
- _blockade_emt.block();
-
- /* next time run - recall() may change this */
- _next_state = RUN;
-
- /* write FPU state of vCPU to pCtx */
- _state->fpu.with_state([&] (Vcpu_state::Fpu::State const &fpu) {
- ::memcpy(pCtx->pXStateR3, &fpu, sizeof(X86FXSTATE));
- });
-
- _state->discharge();
-
- if (_vm_state == IRQ_WIN) {
- _irq_window_pthread();
- goto again;
- } else
- if (_vm_state == NPT_EPT) {
- if (npt_ept_unmap) {
- Genode::error("NPT/EPT unmap not supported - stop");
- while (true) {
- _blockade_emt.block();
- }
- }
-
- Genode::addr_t const gp_map_addr = npt_ept_exit_addr & ~((1UL << 12) - 1);
- int res = attach_memory_to_vm(gp_map_addr, npt_ept_errorcode);
- if (res == VINF_SUCCESS) {
- goto again;
- }
- }
-
- if (!(_vm_state == PAUSED || _vm_state == NPT_EPT))
- Genode::error("which state we are ? ", (int)_vm_state, " ", Genode::Thread::myself()->name());
-
- Assert(_vm_state == PAUSED || _vm_state == NPT_EPT);
- }
-
- void _default_handler()
- {
- if (_vm_state != RUNNING)
- Genode::error(__func__, " _vm_state=", (int)_vm_state, " exit_reason=", Genode::Hex(_state->exit_reason));
- Assert(_vm_state == RUNNING);
-
- Assert(_state->actv_state.value() == ACTIVITY_STATE_ACTIVE);
- Assert(!(_state->inj_info.value() & IRQ_INJ_VALID_MASK));
-
- _vm_exits ++;
-
- _vm_state = PAUSED;
-
- _blockade_emt.wakeup();
- }
-
- bool _recall_handler()
- {
- if (_vm_state != RUNNING)
- Genode::error(__func__, " _vm_state=", (int)_vm_state, " exit_reason=", Genode::Hex(_state->exit_reason));
- Assert(_vm_state == RUNNING);
-
- _vm_exits ++;
- _recall_inv ++;
-
- Assert(_state->actv_state.value() == ACTIVITY_STATE_ACTIVE);
-
- if (_state->inj_info.value() & IRQ_INJ_VALID_MASK) {
-
- Assert(_state->flags.value() & X86_EFL_IF);
-
- if (_state->intr_state.value() != INTERRUPT_STATE_NONE)
- Genode::log("intr state ", Genode::Hex(_state->intr_state.value()),
- " ", Genode::Hex(_state->intr_state.value() & 0xf));
-
- Assert(_state->intr_state.value() == INTERRUPT_STATE_NONE);
-
- if (!continue_hw_accelerated())
- _recall_drop ++;
-
- /* got recall during irq injection and the guest is ready for
- * delivery of IRQ - just continue */
- return /* no-wait */ false;
- }
-
- /* are we forced to go back to emulation mode ? */
- if (!continue_hw_accelerated()) {
- /* go back to emulation mode */
- _default_handler();
- return /* wait */ true;
- }
-
- /* check whether we have to request irq injection window */
- if (check_to_request_irq_window(_vcpu)) {
- _state->discharge();
- _state->inj_info.charge(_state->inj_info.value());
- _irq_win = true;
- return /* no-wait */ false;
- }
-
- _default_handler();
- return /* wait */ true;
- }
-
- inline bool vbox_to_state(VM *pVM, PVMCPU pVCpu)
- {
- typedef Genode::Vcpu_state::Range Range;
-
- PCPUMCTX pCtx = CPUMQueryGuestCtxPtr(pVCpu);
-
- _state->ip.charge(pCtx->rip);
- _state->sp.charge(pCtx->rsp);
-
- _state->ax.charge(pCtx->rax);
- _state->bx.charge(pCtx->rbx);
- _state->cx.charge(pCtx->rcx);
- _state->dx.charge(pCtx->rdx);
-
- _state->bp.charge(pCtx->rbp);
- _state->si.charge(pCtx->rsi);
- _state->di.charge(pCtx->rdi);
-
- _state->r8.charge(pCtx->r8);
- _state->r9.charge(pCtx->r9);
- _state->r10.charge(pCtx->r10);
- _state->r11.charge(pCtx->r11);
- _state->r12.charge(pCtx->r12);
- _state->r13.charge(pCtx->r13);
- _state->r14.charge(pCtx->r14);
- _state->r15.charge(pCtx->r15);
-
- _state->flags.charge(pCtx->rflags.u);
-
- _state->sysenter_cs.charge(pCtx->SysEnter.cs);
- _state->sysenter_sp.charge(pCtx->SysEnter.esp);
- _state->sysenter_ip.charge(pCtx->SysEnter.eip);
-
- _state->dr7.charge(pCtx->dr[7]);
-
- _state->cr0.charge(pCtx->cr0);
- _state->cr2.charge(pCtx->cr2);
- _state->cr3.charge(pCtx->cr3);
- _state->cr4.charge(pCtx->cr4);
-
- _state->idtr.charge(Range { .limit = pCtx->idtr.cbIdt,
- .base = pCtx->idtr.pIdt });
- _state->gdtr.charge(Range { .limit = pCtx->gdtr.cbGdt,
- .base = pCtx->gdtr.pGdt });
-
- _state->efer.charge(CPUMGetGuestEFER(pVCpu));
-
- /*
- * Update the PDPTE registers if necessary
- *
- * Intel manual sections 4.4.1 of Vol. 3A and 26.3.2.4 of Vol. 3C
- * indicate the conditions when this is the case. The following
- * code currently does not check if the recompiler modified any
- * CR registers, which means the update can happen more often
- * than really necessary.
- */
- if (pVM->hm.s.vmx.fSupported &&
- CPUMIsGuestPagingEnabledEx(pCtx) &&
- CPUMIsGuestInPAEModeEx(pCtx)) {
-
- Genode::uint64_t *pdpte = pdpte_map(pVM, pCtx->cr3);
-
- _state->pdpte_0.charge(pdpte[0]);
- _state->pdpte_1.charge(pdpte[1]);
- _state->pdpte_2.charge(pdpte[2]);
- _state->pdpte_3.charge(pdpte[3]);
- }
-
- _state->star.charge(pCtx->msrSTAR);
- _state->lstar.charge(pCtx->msrLSTAR);
- _state->cstar.charge(pCtx->msrCSTAR);
- _state->fmask.charge(pCtx->msrSFMASK);
- _state->kernel_gs_base.charge(pCtx->msrKERNELGSBASE);
-
- /* from HMVMXR0.cpp */
- bool interrupt_pending = false;
- uint8_t tpr = 0;
- uint8_t pending_interrupt = 0;
- PDMApicGetTPR(pVCpu, &tpr, &interrupt_pending, &pending_interrupt);
-
- _state->tpr.charge(tpr);
- _state->tpr_threshold.charge(0);
-
- if (interrupt_pending) {
- const uint8_t pending_priority = (pending_interrupt >> 4) & 0xf;
- const uint8_t tpr_priority = (tpr >> 4) & 0xf;
- if (pending_priority <= tpr_priority)
- _state->tpr_threshold.charge(pending_priority);
- else
- _state->tpr_threshold.charge(tpr_priority);
- }
-
- {
- ::uint64_t tsc_aux = 0;
- auto const rcStrict = CPUMQueryGuestMsr(pVCpu, MSR_K8_TSC_AUX,
- &tsc_aux);
- Assert(rcStrict == VINF_SUCCESS);
- if (rcStrict == VINF_SUCCESS)
- _state->tsc_aux.charge(tsc_aux);
- }
-
- return true;
- }
-
-
- inline bool state_to_vbox(VM *pVM, PVMCPU pVCpu)
- {
- PCPUMCTX pCtx = CPUMQueryGuestCtxPtr(pVCpu);
-
- pCtx->rip = _state->ip.value();
- pCtx->rsp = _state->sp.value();
-
- pCtx->rax = _state->ax.value();
- pCtx->rbx = _state->bx.value();
- pCtx->rcx = _state->cx.value();
- pCtx->rdx = _state->dx.value();
-
- pCtx->rbp = _state->bp.value();
- pCtx->rsi = _state->si.value();
- pCtx->rdi = _state->di.value();
- pCtx->rflags.u = _state->flags.value();
-
- pCtx->r8 = _state->r8.value();
- pCtx->r9 = _state->r9.value();
- pCtx->r10 = _state->r10.value();
- pCtx->r11 = _state->r11.value();
- pCtx->r12 = _state->r12.value();
- pCtx->r13 = _state->r13.value();
- pCtx->r14 = _state->r14.value();
- pCtx->r15 = _state->r15.value();
-
- pCtx->dr[7] = _state->dr7.value();
-
- if (pCtx->SysEnter.cs != _state->sysenter_cs.value())
- CPUMSetGuestMsr(pVCpu, MSR_IA32_SYSENTER_CS, _state->sysenter_cs.value());
-
- if (pCtx->SysEnter.esp != _state->sysenter_sp.value())
- CPUMSetGuestMsr(pVCpu, MSR_IA32_SYSENTER_ESP, _state->sysenter_sp.value());
-
- if (pCtx->SysEnter.eip != _state->sysenter_ip.value())
- CPUMSetGuestMsr(pVCpu, MSR_IA32_SYSENTER_EIP, _state->sysenter_ip.value());
-
- if (pCtx->idtr.cbIdt != _state->idtr.value().limit ||
- pCtx->idtr.pIdt != _state->idtr.value().base)
- CPUMSetGuestIDTR(pVCpu, _state->idtr.value().base, _state->idtr.value().limit);
-
- if (pCtx->gdtr.cbGdt != _state->gdtr.value().limit ||
- pCtx->gdtr.pGdt != _state->gdtr.value().base)
- CPUMSetGuestGDTR(pVCpu, _state->gdtr.value().base, _state->gdtr.value().limit);
-
- CPUMSetGuestEFER(pVCpu, _state->efer.value());
-
- if (pCtx->cr0 != _state->cr0.value())
- CPUMSetGuestCR0(pVCpu, _state->cr0.value());
-
- if (pCtx->cr2 != _state->cr2.value())
- CPUMSetGuestCR2(pVCpu, _state->cr2.value());
-
- if (pCtx->cr3 != _state->cr3.value()) {
- CPUMSetGuestCR3(pVCpu, _state->cr3.value());
- VMCPU_FF_SET(pVCpu, VMCPU_FF_HM_UPDATE_CR3);
- }
-
- if (pCtx->cr4 != _state->cr4.value())
- CPUMSetGuestCR4(pVCpu, _state->cr4.value());
-
- if (pCtx->msrSTAR != _state->star.value())
- CPUMSetGuestMsr(pVCpu, MSR_K6_STAR, _state->star.value());
-
- if (pCtx->msrLSTAR != _state->lstar.value())
- CPUMSetGuestMsr(pVCpu, MSR_K8_LSTAR, _state->lstar.value());
-
- if (pCtx->msrCSTAR != _state->cstar.value())
- CPUMSetGuestMsr(pVCpu, MSR_K8_CSTAR, _state->cstar.value());
-
- if (pCtx->msrSFMASK != _state->fmask.value())
- CPUMSetGuestMsr(pVCpu, MSR_K8_SF_MASK, _state->fmask.value());
-
- if (pCtx->msrKERNELGSBASE != _state->kernel_gs_base.value())
- CPUMSetGuestMsr(pVCpu, MSR_K8_KERNEL_GS_BASE, _state->kernel_gs_base.value());
-
- const uint32_t tpr = _state->tpr.value();
-
- /* reset message transfer descriptor for next invocation */
- Assert (!(_state->inj_info.value() & IRQ_INJ_VALID_MASK));
- next_utcb.ctrl[0] = _state->ctrl_primary.value();
- next_utcb.ctrl[1] = _state->ctrl_secondary.value();
-
- if (_state->intr_state.value() & 3) {
- _state->intr_state.charge(_state->intr_state.value());
- _state->actv_state.charge(ACTIVITY_STATE_ACTIVE);
- }
-
- VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TO_R3);
-
- CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_FPU_REM);
- pVCpu->cpum.s.fUseFlags |= (CPUM_USED_FPU_GUEST | CPUM_USED_FPU_SINCE_REM);
-
- if (_state->intr_state.value() != 0) {
- Assert(_state->intr_state.value() == BLOCKING_BY_STI ||
- _state->intr_state.value() == BLOCKING_BY_MOV_SS);
- EMSetInhibitInterruptsPC(pVCpu, pCtx->rip);
- } else
- VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS);
-
- PDMApicSetTPR(pVCpu, tpr);
-
- return true;
- }
-
-
- inline bool check_to_request_irq_window(PVMCPU pVCpu)
- {
- if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS))
- return false;
-
- if (!TRPMHasTrap(pVCpu) &&
- !VMCPU_FF_IS_PENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC |
- VMCPU_FF_INTERRUPT_PIC)))
- return false;
-
- _irq_request++;
-
- unsigned const vector = 0;
- _state->inj_info.charge(REQ_IRQWIN_EXIT | vector);
-
- return true;
- }
-
-
- void _irq_window()
- {
- if (_vm_state != RUNNING)
- Genode::error(__func__, " _vm_state=", (int)_vm_state, " exit_reason=", Genode::Hex(_state->exit_reason));
- Assert(_vm_state == RUNNING);
-
- _vm_exits ++;
-
- _vm_state = IRQ_WIN;
- _blockade_emt.wakeup();
- }
-
- void _npt_ept()
- {
- if (_vm_state != RUNNING)
- Genode::error(__func__, " _vm_state=", (int)_vm_state, " exit_reason=", Genode::Hex(_state->exit_reason));
- Assert(_vm_state == RUNNING);
-
- _vm_exits ++;
-
- _vm_state = NPT_EPT;
- _blockade_emt.wakeup();
- }
-
- void _irq_window_pthread()
- {
- PVMCPU pVCpu = _vcpu;
-
- Assert(_state->flags.value() & X86_EFL_IF);
- Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS));
- Assert(!(_state->inj_info.value() & IRQ_INJ_VALID_MASK));
-
- Assert(_irq_win);
-
- _irq_win = false;
-
- /* request current tpr state from guest, it may block IRQs */
- PDMApicSetTPR(pVCpu, _state->tpr_threshold.value());
-
- if (!TRPMHasTrap(pVCpu)) {
-
- bool res = VMCPU_FF_TEST_AND_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_NMI);
- if (res)
- Genode::log("NMI was set");
-
- if (VMCPU_FF_IS_PENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC |
- VMCPU_FF_INTERRUPT_PIC))) {
-
- uint8_t irq;
- int rc = PDMGetInterrupt(pVCpu, &irq);
- Assert(RT_SUCCESS(rc));
-
- rc = TRPMAssertTrap(pVCpu, irq, TRPM_HARDWARE_INT);
- Assert(RT_SUCCESS(rc));
- }
-
- if (!TRPMHasTrap(pVCpu)) {
- _irq_drop++;
- /* happens if PDMApicSetTPR (see above) mask IRQ */
- _state->inj_info.charge(IRQ_INJ_NONE);
- Genode::error("virq window pthread aaaaaaa while loop");
- return;
- }
- }
- _irq_inject++;
-
- /*
- * If we have no IRQ for injection, something with requesting the
- * IRQ window went wrong. Probably it was forgotten to be reset.
- */
- Assert(TRPMHasTrap(pVCpu));
-
- /* interrupt can be dispatched */
- uint8_t u8Vector;
- TRPMEVENT enmType;
- SVMEVENT Event;
- RTGCUINT u32ErrorCode;
- RTGCUINTPTR GCPtrFaultAddress;
- uint8_t cbInstr;
-
- Event.u = 0;
-
- /* If a new event is pending, then dispatch it now. */
- int rc = TRPMQueryTrapAll(pVCpu, &u8Vector, &enmType, &u32ErrorCode, 0, 0);
- AssertRC(rc);
- Assert(enmType == TRPM_HARDWARE_INT);
- Assert(u8Vector != X86_XCPT_NMI);
-
- /* Clear the pending trap. */
- rc = TRPMResetTrap(pVCpu);
- AssertRC(rc);
-
- Event.n.u8Vector = u8Vector;
- Event.n.u1Valid = 1;
- Event.n.u32ErrorCode = u32ErrorCode;
-
- Event.n.u3Type = SVM_EVENT_EXTERNAL_IRQ;
-
- _state->inj_info.charge(Event.u);
- _state->inj_error.charge(Event.n.u32ErrorCode);
-
- _last_inj_info = _state->inj_info.value();
- _last_inj_error = _state->inj_error.value();
-
-/*
- Genode::log("type:info:vector ", Genode::Hex(Event.n.u3Type),
- Genode::Hex(utcb->inj_info), Genode::Hex(u8Vector),
- " intr:actv - ", Genode::Hex(utcb->intr_state),
- Genode::Hex(utcb->actv_state), " mtd ",
- Genode::Hex(utcb->mtd));
-*/
- }
-
-
- inline bool continue_hw_accelerated(bool verbose = false)
- {
- uint32_t check_vm = VM_FF_HM_TO_R3_MASK | VM_FF_REQUEST
- | VM_FF_PGM_POOL_FLUSH_PENDING
- | VM_FF_PDM_DMA;
- uint32_t check_vcpu = VMCPU_FF_HM_TO_R3_MASK
- | VMCPU_FF_PGM_SYNC_CR3
- | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL
- | VMCPU_FF_REQUEST;
-
- if (!VM_FF_IS_PENDING(_vm, check_vm) &&
- !VMCPU_FF_IS_PENDING(_vcpu, check_vcpu))
- return true;
-
- Assert(!(VM_FF_IS_PENDING(_vm, VM_FF_PGM_NO_MEMORY)));
-
-#define VERBOSE_VM(flag) \
- do { \
- if (VM_FF_IS_PENDING(_vm, flag)) \
- Genode::log("flag ", flag, " pending"); \
- } while (0)
-
-#define VERBOSE_VMCPU(flag) \
- do { \
- if (VMCPU_FF_IS_PENDING(_vcpu, flag)) \
- Genode::log("flag ", flag, " pending"); \
- } while (0)
-
- if (verbose) {
- /*
- * VM_FF_HM_TO_R3_MASK
- */
- VERBOSE_VM(VM_FF_TM_VIRTUAL_SYNC);
- VERBOSE_VM(VM_FF_PGM_NEED_HANDY_PAGES);
- /* handled by the assertion above */
- /* VERBOSE_VM(VM_FF_PGM_NO_MEMORY); */
- VERBOSE_VM(VM_FF_PDM_QUEUES);
- VERBOSE_VM(VM_FF_EMT_RENDEZVOUS);
-
- VERBOSE_VM(VM_FF_REQUEST);
- VERBOSE_VM(VM_FF_PGM_POOL_FLUSH_PENDING);
- VERBOSE_VM(VM_FF_PDM_DMA);
-
- /*
- * VMCPU_FF_HM_TO_R3_MASK
- */
- VERBOSE_VMCPU(VMCPU_FF_TO_R3);
- /* when this flag gets set, a recall request follows */
- /* VERBOSE_VMCPU(VMCPU_FF_TIMER); */
- VERBOSE_VMCPU(VMCPU_FF_PDM_CRITSECT);
-
- VERBOSE_VMCPU(VMCPU_FF_PGM_SYNC_CR3);
- VERBOSE_VMCPU(VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL);
- VERBOSE_VMCPU(VMCPU_FF_REQUEST);
- }
-
-#undef VERBOSE_VMCPU
-#undef VERBOSE_VM
-
- return false;
- }
-
- virtual bool hw_load_state(Genode::Vcpu_state *, VM *, PVMCPU) = 0;
- virtual bool hw_save_state(Genode::Vcpu_state *, VM *, PVMCPU) = 0;
- virtual int vm_exit_requires_instruction_emulation(PCPUMCTX) = 0;
-
- virtual void pause_vm() = 0;
- virtual int attach_memory_to_vm(RTGCPHYS const,
- RTGCUINT vbox_fault_reason) = 0;
-
- public:
-
- enum Exit_condition
- {
- SVM_NPT = 0xfc,
- SVM_INVALID = 0xfd,
-
- VCPU_STARTUP = 0xfe,
-
- RECALL = 0xff,
- };
-
-
- Vcpu_handler(Genode::Env &env, size_t stack_size,
- Genode::Affinity::Location location,
- unsigned int cpu_id)
- :
- _ep(env, stack_size,
- Genode::String<12>("EP-EMT-", cpu_id).string(), location),
- _cpu_id(cpu_id)
- {
- pthread_mutexattr_t _attr;
- pthread_mutexattr_init(&_attr);
-
- pthread_cond_init(&_cond_wait, nullptr);
-
- pthread_mutexattr_settype(&_attr, PTHREAD_MUTEX_ERRORCHECK);
- pthread_mutex_init(&_mutex, &_attr);
- }
-
- unsigned int cpu_id() { return _cpu_id; }
-
-
- void recall(PVM vm)
- {
- if (!_vm || !_vcpu) {
- _vm = vm;
- _vcpu = &vm->aCpus[_cpu_id];
- }
-
- if (_vm != vm || _vcpu != &vm->aCpus[_cpu_id])
- Genode::error("wrong CPU !?");
-
- _recall_req ++;
-
- if (_irq_win) {
- _recall_skip ++;
- return;
- }
-
- asm volatile ("":::"memory");
-
- if (_vm_state != PAUSED)
- pause_vm();
-
- _next_state = PAUSE_EXIT;
-
-#if 0
- if (_recall_req % 1000 == 0) {
- using Genode::log;
-
- while (other) {
- log(other->_cpu_id, " exits=", other->_vm_exits,
- " req:skip:drop,inv recall=", other->_recall_req, ":",
- other->_recall_skip, ":", other->_recall_drop, ":",
- other->_recall_inv, " req:inj:drop irq=",
- other->_irq_request, ":", other->_irq_inject, ":",
- other->_irq_drop);
-
- other = other->next();
- }
- }
-#endif
- }
-
- void halt(Genode::uint64_t const wait_ns)
- {
- /* calculate timeout */
- timespec ts { 0, 0 };
- clock_gettime(CLOCK_REALTIME, &ts);
- ts = add_timespec_ns(ts, wait_ns);
-
- /* wait for condition or timeout */
- pthread_mutex_lock(&_mutex);
- pthread_cond_timedwait(&_cond_wait, &_mutex, &ts);
- pthread_mutex_unlock(&_mutex);
- }
-
- void wake_up()
- {
- pthread_mutex_lock(&_mutex);
- pthread_cond_signal(&_cond_wait);
- pthread_mutex_unlock(&_mutex);
- }
-
- int run_hw(PVMR0 pVMR0)
- {
- VM * pVM = reinterpret_cast(pVMR0);
- PVMCPU pVCpu = &pVM->aCpus[_cpu_id];
- PCPUMCTX pCtx = CPUMQueryGuestCtxPtr(pVCpu);
-
- if (!_vm || !_vcpu) {
- _vm = pVM;
- _vcpu = &pVM->aCpus[_cpu_id];
- }
-
- if (_vm != pVM || _vcpu != &pVM->aCpus[_cpu_id])
- Genode::error("wrong CPU !?");
-
- /* take the utcb state prepared during the last exit */
- _state->ctrl_primary.charge(next_utcb.ctrl[0]);
- _state->ctrl_secondary.charge(next_utcb.ctrl[1]);
-
- /* Transfer vCPU state from vbox to Genode format */
- if (!vbox_to_state(pVM, pVCpu) ||
- !hw_load_state(_state, pVM, pVCpu)) {
-
- Genode::error("loading vCPU state failed");
- return VERR_INTERNAL_ERROR;
- }
-
- /* check whether to request interrupt window for injection */
- _irq_win = check_to_request_irq_window(pVCpu);
-
- /*
- * Flag vCPU to be "pokeable" by external events such as interrupts
- * from virtual devices. Only if this flag is set, the
- * 'vmR3HaltGlobal1NotifyCpuFF' function calls 'SUPR3CallVMMR0Ex'
- * with VMMR0_DO_GVMM_SCHED_POKE as argument to indicate such
- * events. This function, in turn, will recall the vCPU.
- */
- VMCPU_SET_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC);
-
- /* switch to hardware accelerated mode */
- switch_to_hw(pCtx);
-
- Assert(_state->actv_state.value() == ACTIVITY_STATE_ACTIVE);
-
- /* see hmR0VmxExitToRing3 - sync recompiler state */
- CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_SYSENTER_MSR |
- CPUM_CHANGED_LDTR | CPUM_CHANGED_GDTR |
- CPUM_CHANGED_IDTR | CPUM_CHANGED_TR |
- CPUM_CHANGED_HIDDEN_SEL_REGS |
- CPUM_CHANGED_GLOBAL_TLB_FLUSH);
-
- VMCPU_SET_STATE(pVCpu, VMCPUSTATE_STARTED);
-
- /* Transfer vCPU state from Genode to vbox format */
- if (!state_to_vbox(pVM, pVCpu) ||
- !hw_save_state(_state, pVM, pVCpu)) {
-
- Genode::error("saving vCPU state failed");
- return VERR_INTERNAL_ERROR;
- }
-
-#ifdef VBOX_WITH_REM
- REMFlushTBs(pVM);
-#endif
-
- /* track guest mode changes - see VMM/VMMAll/IEMAllCImpl.cpp.h */
- PGMChangeMode(pVCpu, pCtx->cr0, pCtx->cr4, pCtx->msrEFER);
-
- int rc = vm_exit_requires_instruction_emulation(pCtx);
-
- /* evaluated in VMM/include/EMHandleRCTmpl.h */
- return rc;
- }
-};
-
-#endif /* _VIRTUALBOX__VCPU_H_ */
diff --git a/repos/ports/src/virtualbox5/vcpu_svm.h b/repos/ports/src/virtualbox5/vcpu_svm.h
deleted file mode 100644
index d0124f9a27..0000000000
--- a/repos/ports/src/virtualbox5/vcpu_svm.h
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * \brief Genode specific VirtualBox SUPLib supplements
- * \author Alexander Boettcher
- * \author Norman Feske
- * \author Christian Helmuth
- * \date 2013-11-18
- */
-
-/*
- * Copyright (C) 2013-2021 Genode Labs GmbH
- *
- * This file is distributed under the terms of the GNU General Public License
- * version 2.
- */
-
-#ifndef _VIRTUALBOX__VCPU_SVM_H_
-#define _VIRTUALBOX__VCPU_SVM_H_
-
-/* Genode includes */
-#include
-
-/* Genode's VirtualBox includes */
-#include "vcpu.h"
-#include "svm.h"
-
-class Vcpu_handler_svm : public Vcpu_handler
-{
- private:
-
- Genode::Vcpu_handler _handler;
-
- Genode::Vm_connection &_vm_connection;
- Genode::Vm_connection::Vcpu _vcpu;
-
- void _svm_default() { _default_handler(); }
- void _svm_vintr() { _irq_window(); }
-
- template
- void _svm_npt()
- {
- bool const unmap = _state->qual_primary.value() & 1;
- Genode::addr_t const exit_addr = _state->qual_secondary.value();
- RTGCUINT const vbox_errorcode = _state->qual_primary.value();
-
- npt_ept_exit_addr = exit_addr;
- npt_ept_unmap = unmap;
- npt_ept_errorcode = vbox_errorcode;
-
- _npt_ept();
- }
-
- void _svm_startup()
- {
- /* enable VM exits */
- 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_RDTSC
- | 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_RDTSCP
- | SVM_CTRL2_INTERCEPT_MWAIT;
- }
-
- void _handle_exit()
- {
- unsigned const exit = _state->exit_reason;
- bool recall_wait = true;
-
- switch (exit) {
- case SVM_EXIT_VINTR: _svm_vintr(); break;
- case SVM_NPT: _svm_npt(); break;
- case SVM_EXIT_CPUID:
- case SVM_EXIT_HLT:
- case SVM_EXIT_INVLPGA:
- case SVM_EXIT_IOIO:
- case SVM_EXIT_MSR:
- case SVM_EXIT_READ_CR0 ... SVM_EXIT_WRITE_CR15:
- case SVM_EXIT_RDTSC:
- case SVM_EXIT_RDTSCP:
- case SVM_EXIT_WBINVD:
- _svm_default();
- break;
- case SVM_INVALID:
- Genode::warning("invalid svm ip=", _state->ip.value());
- _svm_default();
- break;
- case SVM_EXIT_SHUTDOWN:
- Genode::error("shutdown exit");
- ::exit(-1);
- break;
- case RECALL:
- recall_wait = Vcpu_handler::_recall_handler();
- break;
- case VCPU_STARTUP:
- _svm_startup();
- _blockade_emt.wakeup();
- /* pause - no resume */
- break;
- default:
- Genode::error(__func__, " unknown exit - stop - ",
- Genode::Hex(exit));
- _vm_state = PAUSED;
- return;
- }
-
- if (exit == RECALL && !recall_wait) {
- _vm_state = RUNNING;
- run_vm();
- return;
- }
-
- /* wait until EMT thread wake's us up */
- _sem_handler.down();
-
- /* resume vCPU */
- _vm_state = RUNNING;
- if (_next_state == RUN)
- run_vm();
- else
- pause_vm(); /* cause pause exit */
- }
-
- void run_vm() { _vcpu.run(); }
- void pause_vm() { _vcpu.pause(); }
-
- int attach_memory_to_vm(RTGCPHYS const gp_attach_addr,
- RTGCUINT vbox_errorcode)
- {
- return map_memory(_vm_connection, gp_attach_addr, vbox_errorcode);
- }
-
- public:
-
- Vcpu_handler_svm(Genode::Env &env, size_t stack_size,
- Genode::Affinity::Location location,
- unsigned int cpu_id,
- Genode::Vm_connection &vm_connection,
- Genode::Allocator &alloc)
- :
- Vcpu_handler(env, stack_size, location, cpu_id),
- _handler(_ep, *this, &Vcpu_handler_svm::_handle_exit),
- _vm_connection(vm_connection),
- _vcpu(_vm_connection, alloc, _handler, _exit_config)
- {
- /* get state of vcpu */
- _state = &_vcpu.state();
-
- _vcpu.run();
-
- /* sync with initial startup exception */
- _blockade_emt.block();
- }
-
- bool hw_save_state(Genode::Vcpu_state *state, VM * pVM, PVMCPU pVCpu) {
- return svm_save_state(state, pVM, pVCpu);
- }
-
- bool hw_load_state(Genode::Vcpu_state *state, VM * pVM, PVMCPU pVCpu) {
- return svm_load_state(state, pVM, pVCpu);
- }
-
- int vm_exit_requires_instruction_emulation(PCPUMCTX)
- {
- if (_state->exit_reason == RECALL)
- return VINF_SUCCESS;
-
- return VINF_EM_RAW_EMULATE_INSTR;
- }
-};
-
-#endif /* _VIRTUALBOX__VCPU_SVM_H_ */
diff --git a/repos/ports/src/virtualbox5/vcpu_vmx.h b/repos/ports/src/virtualbox5/vcpu_vmx.h
deleted file mode 100644
index aa90e1d4dc..0000000000
--- a/repos/ports/src/virtualbox5/vcpu_vmx.h
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * \brief Genode specific VirtualBox SUPLib supplements
- * \author Alexander Boettcher
- * \author Norman Feske
- * \author Christian Helmuth
- * \date 2013-11-18
- */
-
-/*
- * Copyright (C) 2013-2021 Genode Labs GmbH
- *
- * This file is distributed under the terms of the GNU General Public License
- * version 2.
- */
-
-#ifndef _VIRTUALBOX__VCPU_VMX_H_
-#define _VIRTUALBOX__VCPU_VMX_H_
-
-/* Genode includes */
-#include
-
-/* libc includes */
-#include
-
-/* VirtualBox includes */
-#include
-
-/* Genode's VirtualBox includes */
-#include "vcpu.h"
-#include "vmx.h"
-
-
-class Vcpu_handler_vmx : public Vcpu_handler
-{
- private:
-
- Genode::Vcpu_handler _handler;
-
- Genode::Vm_connection &_vm_connection;
- Genode::Vm_connection::Vcpu _vcpu;
-
- template
- void _vmx_ept()
- {
- Genode::addr_t const exit_qual = _state->qual_primary.value();
- Genode::addr_t const exit_addr = _state->qual_secondary.value();
- bool const unmap = exit_qual & 0x38;
-
- RTGCUINT vbox_errorcode = 0;
- if (exit_qual & VMX_EXIT_QUALIFICATION_EPT_INSTR_FETCH)
- vbox_errorcode |= X86_TRAP_PF_ID;
- if (exit_qual & VMX_EXIT_QUALIFICATION_EPT_DATA_WRITE)
- vbox_errorcode |= X86_TRAP_PF_RW;
- if (exit_qual & VMX_EXIT_QUALIFICATION_EPT_ENTRY_PRESENT)
- vbox_errorcode |= X86_TRAP_PF_P;
-
- npt_ept_exit_addr = exit_addr;
- npt_ept_unmap = unmap;
- npt_ept_errorcode = vbox_errorcode;
-
- _npt_ept();
- }
-
- void _vmx_default() { _default_handler(); }
-
- void _vmx_startup()
- {
- /* configure VM exits to get */
- /* from src/VBox/VMM/VMMR0/HWVMXR0.cpp of virtualbox sources */
- next_utcb.ctrl[0] = VMX_VMCS_CTRL_PROC_EXEC_HLT_EXIT |
- VMX_VMCS_CTRL_PROC_EXEC_MOV_DR_EXIT |
- VMX_VMCS_CTRL_PROC_EXEC_UNCOND_IO_EXIT |
-/*
- VMX_VMCS_CTRL_PROC_EXEC_MONITOR_EXIT |
- VMX_VMCS_CTRL_PROC_EXEC_MWAIT_EXIT |
-*/
-/* VMX_VMCS_CTRL_PROC_EXEC_CR8_LOAD_EXIT |
- VMX_VMCS_CTRL_PROC_EXEC_CR8_STORE_EXIT |*/
- VMX_VMCS_CTRL_PROC_EXEC_USE_TPR_SHADOW |
- VMX_VMCS_CTRL_PROC_EXEC_RDPMC_EXIT;
-/* VMX_VMCS_CTRL_PROC_EXEC_PAUSE_EXIT | */
- /*
- * Disable trapping RDTSC for now as it creates a huge load with
- * VM guests that execute it frequently.
- */
- // VMX_VMCS_CTRL_PROC_EXEC_RDTSC_EXIT;
-
- next_utcb.ctrl[1] = VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC |
- VMX_VMCS_CTRL_PROC_EXEC2_WBINVD_EXIT |
- VMX_VMCS_CTRL_PROC_EXEC2_UNRESTRICTED_GUEST |
- VMX_VMCS_CTRL_PROC_EXEC2_VPID |
- VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP |
- VMX_VMCS_CTRL_PROC_EXEC2_EPT |
- VMX_VMCS_CTRL_PROC_EXEC2_INVPCID;
- }
-
- void _vmx_triple()
- {
- Genode::error("triple fault - dead");
- exit(-1);
- }
-
- void _vmx_irqwin() { _irq_window(); }
-
- __attribute__((noreturn)) void _vmx_invalid()
- {
- unsigned const dubious = _state->inj_info.value() |
- _state->intr_state.value() |
- _state->actv_state.value();
- if (dubious)
- Genode::warning(__func__, " - dubious -"
- " inj_info=", Genode::Hex(_state->inj_info.value()),
- " inj_error=", Genode::Hex(_state->inj_error.value()),
- " intr_state=", Genode::Hex(_state->intr_state.value()),
- " actv_state=", Genode::Hex(_state->actv_state.value()));
-
- Genode::error("invalid guest state - dead");
- exit(-1);
- }
-
- void _vmx_mov_crx() { _default_handler(); return; }
-
- void _handle_exit()
- {
- unsigned const exit = _state->exit_reason;
- bool recall_wait = true;
-
- switch (exit) {
- case VMX_EXIT_TRIPLE_FAULT: _vmx_triple(); break;
- case VMX_EXIT_INIT_SIGNAL: _vmx_default(); break;
- case VMX_EXIT_INT_WINDOW: _vmx_irqwin(); break;
- case VMX_EXIT_TASK_SWITCH: _vmx_default(); break;
- case VMX_EXIT_CPUID: _vmx_default(); break;
- case VMX_EXIT_HLT: _vmx_default(); break;
- /* we don't support tsc offsetting for now - so let the rdtsc exit */
- case VMX_EXIT_RDTSC: _vmx_default(); break;
- case VMX_EXIT_RDTSCP: _vmx_default(); break;
- case VMX_EXIT_VMCALL: _vmx_default(); break;
- case VMX_EXIT_IO_INSTR: _vmx_default(); break;
- case VMX_EXIT_RDMSR: _vmx_default(); break;
- case VMX_EXIT_WRMSR: _vmx_default(); break;
- case VMX_EXIT_ERR_INVALID_GUEST_STATE: _vmx_invalid(); break;
- case VMX_EXIT_PAUSE: _vmx_default(); break;
- case VMX_EXIT_WBINVD: _vmx_default(); break;
- case VMX_EXIT_MOV_CRX: _vmx_mov_crx(); break;
- case VMX_EXIT_MOV_DRX: _vmx_default(); break;
- case VMX_EXIT_XSETBV: _vmx_default(); break;
- case VMX_EXIT_TPR_BELOW_THRESHOLD: _vmx_default(); break;
- case VMX_EXIT_EPT_VIOLATION: _vmx_ept(); break;
- case RECALL:
- recall_wait = Vcpu_handler::_recall_handler();
- break;
- case VCPU_STARTUP:
- _vmx_startup();
- _blockade_emt.wakeup();
- /* pause - no resume */
- break;
- default:
- Genode::error(__func__, " unknown exit - stop - ",
- Genode::Hex(exit));
- _vm_state = PAUSED;
- return;
- }
-
- if (exit == RECALL && !recall_wait) {
- _vm_state = RUNNING;
- run_vm();
- return;
- }
-
- /* wait until EMT thread wake's us up */
- _sem_handler.down();
-
- /* resume vCPU */
- _vm_state = RUNNING;
- if (_next_state == RUN)
- run_vm();
- else
- pause_vm(); /* cause pause exit */
- }
-
- void run_vm() { _vcpu.run(); }
- void pause_vm() { _vcpu.pause(); }
-
- int attach_memory_to_vm(RTGCPHYS const gp_attach_addr,
- RTGCUINT vbox_errorcode)
- {
- return map_memory(_vm_connection, gp_attach_addr, vbox_errorcode);
- }
-
- public:
-
- Vcpu_handler_vmx(Genode::Env &env, size_t stack_size,
- Genode::Affinity::Location location,
- unsigned int cpu_id,
- Genode::Vm_connection &vm_connection,
- Genode::Allocator &alloc)
- :
- Vcpu_handler(env, stack_size, location, cpu_id),
- _handler(_ep, *this, &Vcpu_handler_vmx::_handle_exit),
- _vm_connection(vm_connection),
- _vcpu(_vm_connection, alloc, _handler, _exit_config)
- {
- /* get state of vcpu */
- _state = &_vcpu.state();
-
- _vcpu.run();
-
- /* sync with initial startup exception */
- _blockade_emt.block();
- }
-
- bool hw_save_state(Genode::Vcpu_state *state, VM * pVM, PVMCPU pVCpu) {
- return vmx_save_state(state, pVM, pVCpu);
- }
-
- bool hw_load_state(Genode::Vcpu_state * state, VM * pVM, PVMCPU pVCpu) {
- return vmx_load_state(state, pVM, pVCpu);
- }
-
- int vm_exit_requires_instruction_emulation(PCPUMCTX pCtx)
- {
- switch (_state->exit_reason) {
- case VMX_EXIT_HLT:
- pCtx->rip++;
- return VINF_EM_HALT;
- case VMX_EXIT_IO_INSTR:
- /* EMHandleRCTmpl.h does not distinguish READ/WRITE rc */
- return VINF_IOM_R3_IOPORT_WRITE;
- case VMX_EXIT_RDMSR:
- return VINF_CPUM_R3_MSR_READ;
- case VMX_EXIT_WRMSR:
- return VINF_CPUM_R3_MSR_WRITE;
- case VMX_EXIT_TPR_BELOW_THRESHOLD:
- /* the instruction causing the exit has already been executed */
- case RECALL:
- return VINF_SUCCESS;
- case VMX_EXIT_EPT_VIOLATION:
- if (_ept_fault_addr_type == PGMPAGETYPE_MMIO)
- /* EMHandleRCTmpl.h does not distinguish READ/WRITE rc */
- return VINF_IOM_R3_MMIO_READ_WRITE;
- case VMX_EXIT_MOV_DRX:
- /* looks complicated in original R0 code -> emulate instead */
- return VINF_EM_RAW_EMULATE_INSTR;
- default:
- return VINF_EM_RAW_EMULATE_INSTR;
- }
- }
-};
-
-#endif /* _VIRTUALBOX__VCPU_VMX_H_ */
diff --git a/repos/ports/src/virtualbox5/vmx.h b/repos/ports/src/virtualbox5/vmx.h
deleted file mode 100644
index bd8798218e..0000000000
--- a/repos/ports/src/virtualbox5/vmx.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * \brief Genode specific VirtualBox SUPLib supplements
- * \author Norman Feske
- * \author Alexander Boettcher
- * \author Christian Helmuth
- */
-
-/*
- * Copyright (C) 2013-2021 Genode Labs GmbH
- *
- * This file is distributed under the terms of the GNU General Public License
- * version 2.
- */
-
-#ifndef _VIRTUALBOX__VMX_H_
-#define _VIRTUALBOX__VMX_H_
-
-#define GENODE_READ_SELREG_REQUIRED(REG) \
- (pCtx->REG.Sel != state->REG.value().sel) || \
- (pCtx->REG.ValidSel != state->REG.value().sel) || \
- (pCtx->REG.fFlags != CPUMSELREG_FLAGS_VALID) || \
- (pCtx->REG.u32Limit != state->REG.value().limit) || \
- (pCtx->REG.u64Base != state->REG.value().base) || \
- (pCtx->REG.Attr.u != sel_ar_conv_from_genode(state->REG.value().ar))
-
-#define GENODE_READ_SELREG(REG) \
- pCtx->REG.Sel = state->REG.value().sel; \
- pCtx->REG.ValidSel = state->REG.value().sel; \
- pCtx->REG.fFlags = CPUMSELREG_FLAGS_VALID; \
- pCtx->REG.u32Limit = state->REG.value().limit; \
- pCtx->REG.u64Base = state->REG.value().base; \
- pCtx->REG.Attr.u = sel_ar_conv_from_genode(state->REG.value().ar)
-
-static inline bool vmx_save_state(Genode::Vcpu_state * state, VM * pVM, PVMCPU pVCpu)
-{
- PCPUMCTX pCtx = CPUMQueryGuestCtxPtr(pVCpu);
-
- GENODE_READ_SELREG(cs);
- GENODE_READ_SELREG(ds);
- GENODE_READ_SELREG(es);
- GENODE_READ_SELREG(fs);
- GENODE_READ_SELREG(gs);
- GENODE_READ_SELREG(ss);
-
- if (GENODE_READ_SELREG_REQUIRED(ldtr)) {
- GENODE_READ_SELREG(ldtr);
- CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_LDTR);
- }
- if (GENODE_READ_SELREG_REQUIRED(tr)) {
- GENODE_READ_SELREG(tr);
- CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_TR);
- }
-
- return true;
-}
-
-#undef GENODE_READ_SELREG_REQUIRED
-#undef GENODE_READ_SELREG
-
-
-enum { VMCS_SEG_UNUSABLE = 0x10000 };
-
-#define GENODE_WRITE_SELREG(REG) \
- Assert(pCtx->REG.fFlags & CPUMSELREG_FLAGS_VALID); \
- Assert(pCtx->REG.ValidSel == pCtx->REG.Sel); \
- state->REG.charge( Segment{ .sel = pCtx->REG.Sel, \
- .ar = sel_ar_conv_to_genode(pCtx->REG.Attr.u ? : VMCS_SEG_UNUSABLE), \
- .limit = pCtx->REG.u32Limit, \
- .base = pCtx->REG.u64Base });
-
-static inline bool vmx_load_state(Genode::Vcpu_state * state, VM * pVM, PVMCPU pVCpu)
-{
- PCPUMCTX pCtx = CPUMQueryGuestCtxPtr(pVCpu);
-
- typedef Genode::Vcpu_state::Segment Segment;
-
- GENODE_WRITE_SELREG(es);
- GENODE_WRITE_SELREG(ds);
-
- GENODE_WRITE_SELREG(fs);
- GENODE_WRITE_SELREG(gs);
-
- GENODE_WRITE_SELREG(cs);
- GENODE_WRITE_SELREG(ss);
-
- /* ldtr */
- if (pCtx->ldtr.Sel == 0) {
- state->ldtr.charge(Segment { .sel = 0,
- .ar = sel_ar_conv_to_genode(0x82),
- .limit = 0,
- .base = 0 });
- } else {
- state->ldtr.charge(Segment { .sel = pCtx->ldtr.Sel,
- .ar = sel_ar_conv_to_genode(pCtx->ldtr.Attr.u),
- .limit = pCtx->ldtr.u32Limit,
- .base = pCtx->ldtr.u64Base });
- }
-
- /* tr */
- state->tr.charge(Segment { .sel = pCtx->tr.Sel,
- .ar = sel_ar_conv_to_genode(pCtx->tr.Attr.u),
- .limit = pCtx->tr.u32Limit,
- .base = pCtx->tr.u64Base });
-
- return true;
-}
-
-#undef GENODE_WRITE_SELREG
-
-#endif /* _VIRTUALBOX__VMX_H_ */
diff --git a/tool/autopilot.list b/tool/autopilot.list
index 0d13efe99a..8f0c4d2b50 100644
--- a/tool/autopilot.list
+++ b/tool/autopilot.list
@@ -84,11 +84,6 @@ usb_hid_reconnect
vbox5_genode_usb_hid_raw
vbox5_ubuntu_16_04_32
vbox5_ubuntu_16_04_64
-vbox5_vm_ubuntu_16_04_32
-vbox5_vm_ubuntu_16_04_64
-vbox5_vm_win10_64
-vbox5_vm_win7_32
-vbox5_vm_win7_64
vbox5_win10_64
vbox5_win7_32
vbox5_win7_64