mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-24 17:06:18 +04:00
Merge pull request #68 from equation314/rvm
Hypervisor support using RVM
This commit is contained in:
commit
1ab076cfe9
4
.github/workflows/main.yml
vendored
4
.github/workflows/main.yml
vendored
@ -57,5 +57,9 @@ jobs:
|
|||||||
|
|
||||||
- name: Download prebuilt user image
|
- name: Download prebuilt user image
|
||||||
run: cd user && make sfsimg ARCH=${{ matrix.arch }} PREBUILT=1 && cd ..
|
run: cd user && make sfsimg ARCH=${{ matrix.arch }} PREBUILT=1 && cd ..
|
||||||
|
|
||||||
- name: Build kernel
|
- name: Build kernel
|
||||||
run: cd kernel && make build ARCH=${{ matrix.arch }} && cd ..
|
run: cd kernel && make build ARCH=${{ matrix.arch }} && cd ..
|
||||||
|
- name: Build kernel with hypervisor
|
||||||
|
if: runner.os == 'Linux' && matrix.arch == 'x86_64'
|
||||||
|
run: cd kernel && make build ARCH=${{ matrix.arch }} HYPERVISOR=on && cd ..
|
||||||
|
165
kernel/Cargo.lock
generated
165
kernel/Cargo.lock
generated
@ -26,9 +26,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "0.7.10"
|
version = "0.7.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8716408b8bc624ed7f65d223ddb9ac2d044c0547b6fa4b0d554f3a9540496ada"
|
checksum = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
@ -48,16 +48,16 @@ name = "apic"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/rcore-os/apic-rs?rev=fb86bd7#fb86bd7c798608a18cbb48755637d97d4266eb89"
|
source = "git+https://github.com/rcore-os/apic-rs?rev=fb86bd7#fb86bd7c798608a18cbb48755637d97d4266eb89"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bit_field 0.10.0",
|
"bit_field 0.10.1",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"x86",
|
"x86",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.0.0"
|
version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
|
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bare-metal"
|
name = "bare-metal"
|
||||||
@ -78,6 +78,21 @@ dependencies = [
|
|||||||
"volatile",
|
"volatile",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bit-set"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de"
|
||||||
|
dependencies = [
|
||||||
|
"bit-vec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bit-vec"
|
||||||
|
version = "0.6.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5f0dc55f2d8a1a85650ac47858bb001b4c0dd73d79e3c455a842925e68d29cd3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bit_field"
|
name = "bit_field"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
@ -86,9 +101,9 @@ checksum = "ed8765909f9009617974ab6b7d332625b320b33c326b1e9321382ef1999b5d56"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bit_field"
|
name = "bit_field"
|
||||||
version = "0.10.0"
|
version = "0.10.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a165d606cf084741d4ac3a28fb6e9b1eb0bd31f6cd999098cfddb0b2ab381dc0"
|
checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
@ -96,6 +111,14 @@ version = "1.2.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitmap-allocator"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://github.com/rcore-os/bitmap-allocator#03bd9909d0dc85e99f5559b97a163ab81073df83"
|
||||||
|
dependencies = [
|
||||||
|
"bit_field 0.9.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitmap-allocator"
|
name = "bitmap-allocator"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@ -141,9 +164,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.54"
|
version = "1.0.60"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7bbb73db36c1246e9034e307d0fba23f9a2e251faa47ade70c1bd252220c8311"
|
checksum = "ef611cc68ff783f18535d77ddd080185275713d852c4f5cbb6122c462a7a825c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
@ -170,9 +193,9 @@ source = "git+https://github.com/rcore-os/device_tree-rs?rev=eee2c23#eee2c23d50a
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "either"
|
name = "either"
|
||||||
version = "1.5.3"
|
version = "1.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
|
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "embedded-graphics"
|
name = "embedded-graphics"
|
||||||
@ -206,9 +229,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "filetime"
|
name = "filetime"
|
||||||
version = "0.2.10"
|
version = "0.2.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "affc17579b132fc2461adf7c575cc6e8b134ebca52c51f5411388965227dc695"
|
checksum = "3ed85775dcc68644b5c950ac06a2b23768d3bc9390464151aaf27136998dcf9e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
@ -239,15 +262,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.71"
|
version = "0.2.77"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49"
|
checksum = "f2f96b10ec2560088a8e76961b00d47107b3a625fecb76dedb29ee7ccbf98235"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.8"
|
version = "0.4.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
|
checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
@ -269,7 +292,7 @@ name = "mips"
|
|||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
source = "git+https://github.com/Harry-Chen/rust-mips?rev=3b828a2#3b828a2afed97f2769a66cf9cd8239a285804dc0"
|
source = "git+https://github.com/Harry-Chen/rust-mips?rev=3b828a2#3b828a2afed97f2769a66cf9cd8239a285804dc0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bit_field 0.10.0",
|
"bit_field 0.10.1",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -303,9 +326,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-derive"
|
name = "num-derive"
|
||||||
version = "0.3.0"
|
version = "0.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0c8b15b261814f992e33760b1fca9fe8b693d8a65299f20c9901688636cfb746"
|
checksum = "6f09b9841adb6b5e1f89ef7087ea636e0fd94b2851f887c1e3eb5d5f8228fab3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -354,10 +377,16 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "paste"
|
name = "numeric-enum-macro"
|
||||||
version = "0.1.16"
|
version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d508492eeb1e5c38ee696371bf7b9fc33c83d46a7d451606b96458fbbbdc2dec"
|
checksum = "300e4bdb6b46b592948e700ea1ef24a4296491f6a0ee722b258040abd15a3714"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "paste"
|
||||||
|
version = "0.1.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "45ca20c77d80be666aef2b45486da86238fabe33e38306bd3118fe4af33fa880"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"paste-impl",
|
"paste-impl",
|
||||||
"proc-macro-hack",
|
"proc-macro-hack",
|
||||||
@ -365,21 +394,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "paste-impl"
|
name = "paste-impl"
|
||||||
version = "0.1.16"
|
version = "0.1.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "84f328a6a63192b333fce5fbb4be79db6758a4d518dfac6d54412f1492f72d32"
|
checksum = "d95a7db200b97ef370c8e6de0088252f7e0dfff7d047a28528e47456c0fc98b6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro-hack",
|
"proc-macro-hack",
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pc-keyboard"
|
name = "pc-keyboard"
|
||||||
version = "0.5.0"
|
version = "0.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c48392db76c4e9a69e0b3be356c5f97ebb7b14413c5e4fd0af4755dbf86e2fce"
|
checksum = "5c6f2d937e3b8d63449b01401e2bae4041bc9dd1129c2e3e0d239407cf6635ac"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pci"
|
name = "pci"
|
||||||
@ -391,15 +417,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro-hack"
|
name = "proc-macro-hack"
|
||||||
version = "0.5.16"
|
version = "0.5.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7e0456befd48169b9f13ef0f0ad46d492cf9d2dbb918bcf38e01eed4ce3ec5e4"
|
checksum = "99c605b9a0adc77b7211c6b1f722dcb613d68d66859a44f3d485a6da332b0598"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.18"
|
version = "1.0.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa"
|
checksum = "36e28516df94f3dd551a587da5357459d9b36d945a7c37c3557928c1c2ff2a2c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
@ -450,9 +476,9 @@ dependencies = [
|
|||||||
"aml",
|
"aml",
|
||||||
"apic",
|
"apic",
|
||||||
"bcm2837",
|
"bcm2837",
|
||||||
"bit_field 0.10.0",
|
"bit_field 0.10.1",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"bitmap-allocator",
|
"bitmap-allocator 0.1.0 (git+https://github.com/rcore-os/bitmap-allocator?rev=03bd9909)",
|
||||||
"bitvec",
|
"bitvec",
|
||||||
"buddy_system_allocator",
|
"buddy_system_allocator",
|
||||||
"compression",
|
"compression",
|
||||||
@ -480,6 +506,7 @@ dependencies = [
|
|||||||
"rcore-memory",
|
"rcore-memory",
|
||||||
"riscv",
|
"riscv",
|
||||||
"rlibc",
|
"rlibc",
|
||||||
|
"rvm",
|
||||||
"smoltcp",
|
"smoltcp",
|
||||||
"spin",
|
"spin",
|
||||||
"trapframe",
|
"trapframe",
|
||||||
@ -563,9 +590,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.1.56"
|
version = "0.1.57"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
|
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
@ -600,7 +627,7 @@ version = "0.5.6"
|
|||||||
source = "git+https://github.com/rcore-os/riscv?rev=38f3786#38f3786966ba15cc76977375162e3f3622a30f4b"
|
source = "git+https://github.com/rcore-os/riscv?rev=38f3786#38f3786966ba15cc76977375162e3f3622a30f4b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bare-metal",
|
"bare-metal",
|
||||||
"bit_field 0.10.0",
|
"bit_field 0.10.1",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"log",
|
"log",
|
||||||
"riscv-target",
|
"riscv-target",
|
||||||
@ -633,15 +660,43 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustversion"
|
name = "rustversion"
|
||||||
version = "1.0.2"
|
version = "1.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b3bba175698996010c4f6dce5e7f173b6eb781fce25d2cfc45e27091ce0b79f6"
|
checksum = "b9bdc5e856e51e685846fb6c13a1f5e5432946c2c90501bdc76a1319f19e29da"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rvm"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "git+https://github.com/rcore-os/RVM?rev=939eb0a#939eb0aafd100e9944e4f2fe90eebfa8149d2b85"
|
||||||
|
dependencies = [
|
||||||
|
"bit-set",
|
||||||
|
"bit_field 0.10.1",
|
||||||
|
"bitflags",
|
||||||
|
"bitmap-allocator 0.1.0 (git+https://github.com/rcore-os/bitmap-allocator)",
|
||||||
|
"lazy_static",
|
||||||
|
"log",
|
||||||
|
"numeric-enum-macro",
|
||||||
|
"raw-cpuid",
|
||||||
|
"rvm_macros",
|
||||||
|
"spin",
|
||||||
|
"x86",
|
||||||
|
"x86_64",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rvm_macros"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://github.com/rcore-os/RVM?rev=939eb0a#939eb0aafd100e9944e4f2fe90eebfa8149d2b85"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "semver"
|
name = "semver"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
@ -682,9 +737,9 @@ checksum = "7f3eb36b47e512f8f1c9e3d10c2c1965bc992bd9cdb024fa581e2194501c83d3"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.31"
|
version = "1.0.41"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b5304cfdf27365b7585c25d4af91b35016ed21ef88f17ced89c7093b43dba8b6"
|
checksum = "6690e3e9f692504b941dc6c3b188fd28df054f7fb8469ab40680df52fdcc842b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -737,7 +792,7 @@ version = "0.3.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "85061f4e43545a613c0da6b87725bf23f8da8613cf2473719c4f71a270c4ce8a"
|
checksum = "85061f4e43545a613c0da6b87725bf23f8da8613cf2473719c4f71a270c4ce8a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bit_field 0.10.0",
|
"bit_field 0.10.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -754,9 +809,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uefi-macros"
|
name = "uefi-macros"
|
||||||
version = "0.3.2"
|
version = "0.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7a69fa8dd920e84d783769c44560484ade81f6c765cde2e1cc46c754ddf95947"
|
checksum = "3dcca10ca861f34a320d178f3fdb29ffbf05087fc2c70d2a99860e3329bee1a8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -765,9 +820,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "unicode-xid"
|
||||||
version = "0.2.0"
|
version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
|
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "usize_conversions"
|
name = "usize_conversions"
|
||||||
@ -799,9 +854,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "volatile"
|
name = "volatile"
|
||||||
version = "0.2.6"
|
version = "0.2.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6af0edf5b4faacc31fc51159244d78d65ec580f021afcef7bd53c04aeabc7f29"
|
checksum = "f6b06ad3ed06fef1713569d547cdbdb439eafed76341820fb0e0344f29a41945"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vte"
|
name = "vte"
|
||||||
@ -814,9 +869,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.8"
|
version = "0.3.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
|
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winapi-i686-pc-windows-gnu",
|
"winapi-i686-pc-windows-gnu",
|
||||||
"winapi-x86_64-pc-windows-gnu",
|
"winapi-x86_64-pc-windows-gnu",
|
||||||
@ -846,16 +901,16 @@ version = "0.33.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2786ac694ed572ab5d2bbcd9e188805dba26b3501973dd69718914fb3d4a5a69"
|
checksum = "2786ac694ed572ab5d2bbcd9e188805dba26b3501973dd69718914fb3d4a5a69"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bit_field 0.10.0",
|
"bit_field 0.10.1",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"raw-cpuid",
|
"raw-cpuid",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "x86_64"
|
name = "x86_64"
|
||||||
version = "0.11.0"
|
version = "0.11.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "365de37eb7c6da582cbb510dd0f3f1235d24ff6309a8a96e8a9909cc9bfd608f"
|
checksum = "aa580d2cf2a6a8c55f6283d6d06271b1ccab4d93cb3741edab290d5408d848c4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bit_field 0.9.0",
|
"bit_field 0.9.0",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
|
@ -36,6 +36,8 @@ link_user = []
|
|||||||
run_cmdline = []
|
run_cmdline = []
|
||||||
# Add performance profiling
|
# Add performance profiling
|
||||||
profile = []
|
profile = []
|
||||||
|
# Rcore Virtual machine
|
||||||
|
hypervisor = ["rvm"]
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
# MUST >= 2 : Enable RVO to avoid stack overflow
|
# MUST >= 2 : Enable RVO to avoid stack overflow
|
||||||
@ -74,6 +76,7 @@ virtio-drivers = { git = "https://github.com/rcore-os/virtio-drivers", rev = "df
|
|||||||
volatile = "0.2"
|
volatile = "0.2"
|
||||||
woke = "0.0.2"
|
woke = "0.0.2"
|
||||||
xmas-elf = "0.7"
|
xmas-elf = "0.7"
|
||||||
|
rvm = { git = "https://github.com/rcore-os/RVM", rev = "939eb0a", optional = true }
|
||||||
|
|
||||||
[target.'cfg(target_arch = "x86_64")'.dependencies]
|
[target.'cfg(target_arch = "x86_64")'.dependencies]
|
||||||
apic = { git = "https://github.com/rcore-os/apic-rs", rev = "fb86bd7" }
|
apic = { git = "https://github.com/rcore-os/apic-rs", rev = "fb86bd7" }
|
||||||
@ -93,4 +96,4 @@ bcm2837 = { git = "https://github.com/rcore-os/bcm2837", version = "2.5.1", opti
|
|||||||
|
|
||||||
[target.'cfg(target_arch = "mips")'.dependencies]
|
[target.'cfg(target_arch = "mips")'.dependencies]
|
||||||
mips = { git = "https://github.com/Harry-Chen/rust-mips", rev = "3b828a2" }
|
mips = { git = "https://github.com/Harry-Chen/rust-mips", rev = "3b828a2" }
|
||||||
paste = "0.1"
|
paste = "0.1"
|
||||||
|
@ -26,6 +26,8 @@
|
|||||||
# PCI_PASSTHRU = 0000:00:00.1 [ x86_64 only] Passthrough the specified PCI device
|
# PCI_PASSTHRU = 0000:00:00.1 [ x86_64 only] Passthrough the specified PCI device
|
||||||
# INIT = /bin/ls [riscv64 only] Run specified program instead of user shell
|
# INIT = /bin/ls [riscv64 only] Run specified program instead of user shell
|
||||||
# EXTRA_NIC = on | off [ x86_64 only] Add an additional e1000 nic
|
# EXTRA_NIC = on | off [ x86_64 only] Add an additional e1000 nic
|
||||||
|
# ACCEL = on | off [ x86_64 only] Enable/disable kvm/hvf acceleration
|
||||||
|
# HYPERVISOR = on | off [ x86_64 only] Enable/disable the RVM hypervisor, and set ACCEL to on
|
||||||
# FEATURES = profile | ... Add additional features
|
# FEATURES = profile | ... Add additional features
|
||||||
|
|
||||||
ARCH ?= riscv64
|
ARCH ?= riscv64
|
||||||
@ -36,6 +38,8 @@ SMP ?= 4
|
|||||||
PCI_PASSTHRU ?=
|
PCI_PASSTHRU ?=
|
||||||
INIT ?=
|
INIT ?=
|
||||||
EXTRA_NIC ?= off
|
EXTRA_NIC ?= off
|
||||||
|
ACCEL ?= off
|
||||||
|
HYPERVISOR ?= off
|
||||||
|
|
||||||
qemu := qemu-system-$(ARCH)
|
qemu := qemu-system-$(ARCH)
|
||||||
target := $(ARCH)
|
target := $(ARCH)
|
||||||
@ -93,10 +97,6 @@ qemu_net_opts += \
|
|||||||
qemu_ui_opts += \
|
qemu_ui_opts += \
|
||||||
-vga std
|
-vga std
|
||||||
endif
|
endif
|
||||||
ifeq ($(shell uname), Darwin)
|
|
||||||
qemu_opts += \
|
|
||||||
-machine accel=hvf
|
|
||||||
endif
|
|
||||||
ifeq ($(EXTRA_NIC), on)
|
ifeq ($(EXTRA_NIC), on)
|
||||||
qemu_net_opts += \
|
qemu_net_opts += \
|
||||||
-netdev type=tap,id=net1,script=no,downscript=no \
|
-netdev type=tap,id=net1,script=no,downscript=no \
|
||||||
@ -171,6 +171,19 @@ qemu_opts += $(qemu_net_opts)
|
|||||||
qemu := sudo $(qemu)
|
qemu := sudo $(qemu)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(HYPERVISOR), on)
|
||||||
|
FEATURES += hypervisor
|
||||||
|
ACCEL = on
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(ACCEL), on)
|
||||||
|
ifeq ($(shell uname), Darwin)
|
||||||
|
qemu_opts += -accel hvf
|
||||||
|
else
|
||||||
|
qemu_opts += -accel kvm -cpu host
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
### build args ###
|
### build args ###
|
||||||
ifeq ($(GRAPHIC), off)
|
ifeq ($(GRAPHIC), off)
|
||||||
FEATURES += nographic
|
FEATURES += nographic
|
||||||
|
@ -83,6 +83,9 @@ lazy_static! {
|
|||||||
devfs.add("fb0", Arc::new(Fbdev::default())).expect("failed to mknod /dev/fb0");
|
devfs.add("fb0", Arc::new(Fbdev::default())).expect("failed to mknod /dev/fb0");
|
||||||
devfs.add("shm", Arc::new(ShmINode::default())).expect("failed to mkdir shm");
|
devfs.add("shm", Arc::new(ShmINode::default())).expect("failed to mkdir shm");
|
||||||
|
|
||||||
|
#[cfg(feature = "hypervisor")]
|
||||||
|
devfs.add("rvm", Arc::new(crate::rvm::RvmINode::new())).expect("failed to mknod /dev/rvm");
|
||||||
|
|
||||||
// mount DevFS at /dev
|
// mount DevFS at /dev
|
||||||
let dev = root.find(true, "dev").unwrap_or_else(|_| {
|
let dev = root.find(true, "dev").unwrap_or_else(|_| {
|
||||||
root.create("dev", FileType::Dir, 0o666).expect("failed to mkdir /dev")
|
root.create("dev", FileType::Dir, 0o666).expect("failed to mkdir /dev")
|
||||||
|
@ -21,8 +21,6 @@
|
|||||||
#![allow(unused_mut)]
|
#![allow(unused_mut)]
|
||||||
#![allow(unused_variables)]
|
#![allow(unused_variables)]
|
||||||
#![allow(unused_imports)]
|
#![allow(unused_imports)]
|
||||||
#![allow(unreachable_patterns)]
|
|
||||||
#![allow(unused_assignments)]
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
// just keep it ...
|
// just keep it ...
|
||||||
@ -54,6 +52,8 @@ pub mod lkm;
|
|||||||
pub mod memory;
|
pub mod memory;
|
||||||
pub mod net;
|
pub mod net;
|
||||||
pub mod process;
|
pub mod process;
|
||||||
|
#[cfg(feature = "hypervisor")]
|
||||||
|
pub mod rvm;
|
||||||
pub mod shell;
|
pub mod shell;
|
||||||
pub mod signal;
|
pub mod signal;
|
||||||
pub mod sync;
|
pub mod sync;
|
||||||
|
367
kernel/src/rvm/inode.rs
Normal file
367
kernel/src/rvm/inode.rs
Normal file
@ -0,0 +1,367 @@
|
|||||||
|
//! Implement INode for Rcore Virtual Machine
|
||||||
|
|
||||||
|
use alloc::collections::BTreeMap;
|
||||||
|
use core::any::Any;
|
||||||
|
use core::convert::{TryFrom, TryInto};
|
||||||
|
use core::mem::size_of;
|
||||||
|
use spin::RwLock;
|
||||||
|
|
||||||
|
use rcore_fs::vfs::*;
|
||||||
|
use rvm::{RvmError, RvmExitPacket, RvmResult, TrapKind, VcpuIo, VcpuReadWriteKind, VcpuState};
|
||||||
|
|
||||||
|
use super::into_fs_error;
|
||||||
|
use super::structs::{Guest, Vcpu};
|
||||||
|
use crate::syscall::{UserInOutPtr, UserInPtr, UserOutPtr};
|
||||||
|
|
||||||
|
const MAX_GUEST_NUM: usize = 64;
|
||||||
|
const MAX_VCPU_NUM: usize = 64;
|
||||||
|
|
||||||
|
const RVM_IO: u32 = 0xAE00;
|
||||||
|
const RVM_GUEST_CREATE: u32 = RVM_IO + 0x01;
|
||||||
|
const RVM_GUEST_ADD_MEMORY_REGION: u32 = RVM_IO + 0x02;
|
||||||
|
const RVM_GUEST_SET_TRAP: u32 = RVM_IO + 0x03;
|
||||||
|
const RVM_VCPU_CREATE: u32 = RVM_IO + 0x11;
|
||||||
|
const RVM_VCPU_RESUME: u32 = RVM_IO + 0x12;
|
||||||
|
const RVM_VCPU_READ_STATE: u32 = RVM_IO + 0x13;
|
||||||
|
const RVM_VCPU_WRITE_STATE: u32 = RVM_IO + 0x14;
|
||||||
|
const RVM_VCPU_INTERRUPT: u32 = RVM_IO + 0x15;
|
||||||
|
|
||||||
|
pub struct RvmINode {
|
||||||
|
guests: RwLock<BTreeMap<usize, Guest>>,
|
||||||
|
vcpus: RwLock<BTreeMap<usize, Vcpu>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct RvmVcpuCreateArgs {
|
||||||
|
vmid: u16,
|
||||||
|
entry: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct RvmGuestAddMemoryRegionArgs {
|
||||||
|
vmid: u16,
|
||||||
|
guest_start_paddr: u64,
|
||||||
|
memory_size: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct RvmGuestSetTrapArgs {
|
||||||
|
vmid: u16,
|
||||||
|
kind: u32,
|
||||||
|
addr: u64,
|
||||||
|
size: u64,
|
||||||
|
key: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct RvmVcpuResumeArgs {
|
||||||
|
vcpu_id: u16,
|
||||||
|
packet: RvmExitPacket,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct RvmVcpuStateArgs {
|
||||||
|
vcpu_id: u16,
|
||||||
|
kind: u32,
|
||||||
|
user_buf_ptr: u64,
|
||||||
|
buf_size: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct RvmVcpuInterruptArgs {
|
||||||
|
vcpu_id: u16,
|
||||||
|
vector: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl INode for RvmINode {
|
||||||
|
fn read_at(&self, _offset: usize, _buf: &mut [u8]) -> Result<usize> {
|
||||||
|
Err(FsError::NotSupported)
|
||||||
|
}
|
||||||
|
fn write_at(&self, _offset: usize, _buf: &[u8]) -> Result<usize> {
|
||||||
|
Err(FsError::NotSupported)
|
||||||
|
}
|
||||||
|
fn poll(&self) -> Result<PollStatus> {
|
||||||
|
Ok(PollStatus {
|
||||||
|
read: false,
|
||||||
|
write: false,
|
||||||
|
error: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
fn metadata(&self) -> Result<Metadata> {
|
||||||
|
Ok(Metadata {
|
||||||
|
dev: 0,
|
||||||
|
inode: 0,
|
||||||
|
size: 0,
|
||||||
|
blk_size: 0,
|
||||||
|
blocks: 0,
|
||||||
|
atime: Timespec { sec: 0, nsec: 0 },
|
||||||
|
mtime: Timespec { sec: 0, nsec: 0 },
|
||||||
|
ctime: Timespec { sec: 0, nsec: 0 },
|
||||||
|
type_: FileType::CharDevice,
|
||||||
|
mode: 0o660,
|
||||||
|
nlinks: 1,
|
||||||
|
uid: 0,
|
||||||
|
gid: 0,
|
||||||
|
rdev: make_rdev(10, 232), // misc major, kvm minor
|
||||||
|
})
|
||||||
|
}
|
||||||
|
fn io_control(&self, cmd: u32, data: usize) -> Result<usize> {
|
||||||
|
match cmd {
|
||||||
|
RVM_GUEST_CREATE => {
|
||||||
|
info!("[RVM] ioctl RVM_GUEST_CREATE");
|
||||||
|
self.guest_create().map_err(into_fs_error)
|
||||||
|
}
|
||||||
|
RVM_GUEST_ADD_MEMORY_REGION => {
|
||||||
|
let args = UserInPtr::<RvmGuestAddMemoryRegionArgs>::from(data)
|
||||||
|
.read()
|
||||||
|
.or(Err(FsError::InvalidParam))?;
|
||||||
|
info!("[RVM] ioctl RVM_GUEST_ADD_MEMORY_REGION {:x?}", args);
|
||||||
|
self.guest_add_memory_region(
|
||||||
|
args.vmid as usize,
|
||||||
|
args.guest_start_paddr as usize,
|
||||||
|
args.memory_size as usize,
|
||||||
|
)
|
||||||
|
.map_err(into_fs_error)
|
||||||
|
}
|
||||||
|
RVM_GUEST_SET_TRAP => {
|
||||||
|
let args = UserInPtr::<RvmGuestSetTrapArgs>::from(data)
|
||||||
|
.read()
|
||||||
|
.or(Err(FsError::InvalidParam))?;
|
||||||
|
info!("[RVM] ioctl RVM_GUEST_SET_TRAP {:x?}", args);
|
||||||
|
self.guest_set_trap(
|
||||||
|
args.vmid as usize,
|
||||||
|
args.kind.try_into().map_err(into_fs_error)?,
|
||||||
|
args.addr as usize,
|
||||||
|
args.size as usize,
|
||||||
|
args.key,
|
||||||
|
)
|
||||||
|
.map_err(into_fs_error)?;
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
RVM_VCPU_CREATE => {
|
||||||
|
let args = UserInPtr::<RvmVcpuCreateArgs>::from(data)
|
||||||
|
.read()
|
||||||
|
.or(Err(FsError::InvalidParam))?;
|
||||||
|
info!("[RVM] ioctl RVM_VCPU_CREATE {:x?}", args);
|
||||||
|
self.vcpu_create(args.vmid as usize, args.entry)
|
||||||
|
.map_err(into_fs_error)
|
||||||
|
}
|
||||||
|
RVM_VCPU_RESUME => {
|
||||||
|
let mut ptr = UserInOutPtr::<RvmVcpuResumeArgs>::from(data);
|
||||||
|
let mut args = ptr.read().or(Err(FsError::InvalidParam))?;
|
||||||
|
info!("[RVM] ioctl RVM_VCPU_RESUME {:#x}", args.vcpu_id);
|
||||||
|
args.packet = self
|
||||||
|
.vcpu_resume(args.vcpu_id as usize)
|
||||||
|
.map_err(into_fs_error)?;
|
||||||
|
ptr.write(args).or(Err(FsError::DeviceError))?;
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
RVM_VCPU_READ_STATE => {
|
||||||
|
let args = UserInPtr::<RvmVcpuStateArgs>::from(data)
|
||||||
|
.read()
|
||||||
|
.or(Err(FsError::InvalidParam))?;
|
||||||
|
info!("[RVM] ioctl RVM_VCPU_READ_STATE {:#x?}", args);
|
||||||
|
self.vcpu_read_state(
|
||||||
|
args.vcpu_id as usize,
|
||||||
|
args.kind,
|
||||||
|
args.user_buf_ptr as usize,
|
||||||
|
args.buf_size as usize,
|
||||||
|
)
|
||||||
|
.map_err(into_fs_error)?;
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
RVM_VCPU_WRITE_STATE => {
|
||||||
|
let args = UserInPtr::<RvmVcpuStateArgs>::from(data)
|
||||||
|
.read()
|
||||||
|
.or(Err(FsError::InvalidParam))?;
|
||||||
|
info!("[RVM] ioctl RVM_VCPU_WRITE_STATE {:#x?}", args);
|
||||||
|
self.vcpu_write_state(
|
||||||
|
args.vcpu_id as usize,
|
||||||
|
args.kind,
|
||||||
|
args.user_buf_ptr as usize,
|
||||||
|
args.buf_size as usize,
|
||||||
|
)
|
||||||
|
.map_err(into_fs_error)?;
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
RVM_VCPU_INTERRUPT => {
|
||||||
|
let args = UserInPtr::<RvmVcpuInterruptArgs>::from(data)
|
||||||
|
.read()
|
||||||
|
.or(Err(FsError::InvalidParam))?;
|
||||||
|
info!("[RVM] ioctl RVM_VCPU_INTERRUPT {:#x?}", args);
|
||||||
|
self.vcpu_interrupt(args.vcpu_id as usize, args.vector)
|
||||||
|
.map_err(into_fs_error)?;
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
warn!("[RVM] invalid ioctl number {:#x}", cmd);
|
||||||
|
Err(FsError::InvalidParam)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn mmap(&self, area: MMapArea) -> Result<()> {
|
||||||
|
info!("[RVM] mmap {:x?}", area);
|
||||||
|
Err(FsError::NotSupported)
|
||||||
|
}
|
||||||
|
fn as_any_ref(&self) -> &dyn Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RvmINode {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
guests: RwLock::new(BTreeMap::new()),
|
||||||
|
vcpus: RwLock::new(BTreeMap::new()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_free_vmid(&self) -> usize {
|
||||||
|
(1..).find(|i| !self.guests.read().contains_key(i)).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_guest(&self, guest: Guest, vmid_option: Option<usize>) -> usize {
|
||||||
|
let vmid = vmid_option.unwrap_or_else(|| self.get_free_vmid());
|
||||||
|
self.guests.write().insert(vmid, guest);
|
||||||
|
vmid
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_free_vcpu_id(&self) -> usize {
|
||||||
|
(1..).find(|i| !self.vcpus.read().contains_key(i)).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_vcpu(&self, vcpu: Vcpu, vcpu_id_option: Option<usize>) -> usize {
|
||||||
|
let vcpu_id = vcpu_id_option.unwrap_or_else(|| self.get_free_vcpu_id());
|
||||||
|
self.vcpus.write().insert(vcpu_id, vcpu);
|
||||||
|
vcpu_id
|
||||||
|
}
|
||||||
|
|
||||||
|
fn guest_create(&self) -> RvmResult<usize> {
|
||||||
|
if rvm::check_hypervisor_feature() {
|
||||||
|
let vmid = self.get_free_vmid();
|
||||||
|
if vmid >= MAX_GUEST_NUM {
|
||||||
|
warn!("[RVM] too many guests ({})", MAX_GUEST_NUM);
|
||||||
|
return Err(RvmError::NoMemory);
|
||||||
|
}
|
||||||
|
self.add_guest(Guest::new()?, Some(vmid));
|
||||||
|
Ok(vmid)
|
||||||
|
} else {
|
||||||
|
warn!("[RVM] no hardware support");
|
||||||
|
Err(RvmError::NotSupported)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn guest_add_memory_region(&self, vmid: usize, gpaddr: usize, size: usize) -> RvmResult<usize> {
|
||||||
|
if let Some(guest) = self.guests.read().get(&vmid) {
|
||||||
|
Ok(guest.add_memory_region(gpaddr, size)?)
|
||||||
|
} else {
|
||||||
|
Err(RvmError::InvalidParam)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn guest_set_trap(
|
||||||
|
&self,
|
||||||
|
vmid: usize,
|
||||||
|
kind: TrapKind,
|
||||||
|
addr: usize,
|
||||||
|
size: usize,
|
||||||
|
key: u64,
|
||||||
|
) -> RvmResult<()> {
|
||||||
|
if let Some(guest) = self.guests.read().get(&vmid) {
|
||||||
|
guest.inner.set_trap(kind, addr, size, None, key)
|
||||||
|
} else {
|
||||||
|
Err(RvmError::InvalidParam)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn vcpu_create(&self, vmid: usize, entry: u64) -> RvmResult<usize> {
|
||||||
|
if let Some(guest) = self.guests.read().get(&vmid) {
|
||||||
|
let vcpu_id = self.get_free_vcpu_id();
|
||||||
|
if vcpu_id >= MAX_VCPU_NUM {
|
||||||
|
warn!("[RVM] too many vcpus ({})", MAX_VCPU_NUM);
|
||||||
|
return Err(RvmError::NoMemory);
|
||||||
|
}
|
||||||
|
let vcpu = Vcpu::new(entry, guest.inner.clone())?;
|
||||||
|
self.add_vcpu(vcpu, Some(vcpu_id));
|
||||||
|
Ok(vcpu_id)
|
||||||
|
} else {
|
||||||
|
Err(RvmError::InvalidParam)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn vcpu_resume(&self, vcpu_id: usize) -> RvmResult<RvmExitPacket> {
|
||||||
|
if let Some(vcpu) = self.vcpus.write().get_mut(&vcpu_id) {
|
||||||
|
Ok(vcpu.inner.lock().resume()?)
|
||||||
|
} else {
|
||||||
|
Err(RvmError::InvalidParam)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn vcpu_read_state(
|
||||||
|
&self,
|
||||||
|
vcpu_id: usize,
|
||||||
|
kind: u32,
|
||||||
|
user_buf_ptr: usize,
|
||||||
|
buf_size: usize,
|
||||||
|
) -> RvmResult<()> {
|
||||||
|
if kind != VcpuReadWriteKind::VcpuState as u32 || buf_size != size_of::<VcpuState>() {
|
||||||
|
return Err(RvmError::InvalidParam);
|
||||||
|
}
|
||||||
|
if let Some(vcpu) = self.vcpus.read().get(&vcpu_id) {
|
||||||
|
let mut ptr = UserOutPtr::<VcpuState>::from(user_buf_ptr);
|
||||||
|
let state = vcpu.inner.lock().read_state()?;
|
||||||
|
ptr.write(state).or(Err(RvmError::InvalidParam))?;
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(RvmError::InvalidParam)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn vcpu_write_state(
|
||||||
|
&self,
|
||||||
|
vcpu_id: usize,
|
||||||
|
kind: u32,
|
||||||
|
user_buf_ptr: usize,
|
||||||
|
buf_size: usize,
|
||||||
|
) -> RvmResult<()> {
|
||||||
|
if let Some(vcpu) = self.vcpus.write().get_mut(&vcpu_id) {
|
||||||
|
match VcpuReadWriteKind::try_from(kind) {
|
||||||
|
Ok(VcpuReadWriteKind::VcpuState) => {
|
||||||
|
if buf_size != size_of::<VcpuState>() {
|
||||||
|
return Err(RvmError::InvalidParam);
|
||||||
|
}
|
||||||
|
let ptr = UserInPtr::<VcpuState>::from(user_buf_ptr);
|
||||||
|
let state = ptr.read().or(Err(RvmError::InvalidParam))?;
|
||||||
|
vcpu.inner.lock().write_state(&state)
|
||||||
|
}
|
||||||
|
Ok(VcpuReadWriteKind::VcpuIo) => {
|
||||||
|
if buf_size != size_of::<VcpuIo>() {
|
||||||
|
return Err(RvmError::InvalidParam);
|
||||||
|
}
|
||||||
|
let ptr = UserInPtr::<VcpuIo>::from(user_buf_ptr);
|
||||||
|
let state = ptr.read().or(Err(RvmError::InvalidParam))?;
|
||||||
|
vcpu.inner.lock().write_io_state(&state)
|
||||||
|
}
|
||||||
|
Err(_) => return Err(RvmError::InvalidParam),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Err(RvmError::InvalidParam)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn vcpu_interrupt(&self, vcpu_id: usize, vector: u32) -> RvmResult<()> {
|
||||||
|
if let Some(vcpu) = self.vcpus.write().get_mut(&vcpu_id) {
|
||||||
|
vcpu.inner.lock().virtual_interrupt(vector)
|
||||||
|
} else {
|
||||||
|
Err(RvmError::InvalidParam)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: remove guest & vcpu
|
||||||
|
}
|
97
kernel/src/rvm/memory.rs
Normal file
97
kernel/src/rvm/memory.rs
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
//! Used for delay mapping host's virtual memory to guest's physical memory
|
||||||
|
|
||||||
|
use alloc::{boxed::Box, sync::Arc};
|
||||||
|
|
||||||
|
use rvm::RvmPageTable;
|
||||||
|
use rvm::{DefaultGuestPhysMemorySet, GuestMemoryAttr, GuestPhysAddr, HostVirtAddr};
|
||||||
|
|
||||||
|
use rcore_memory::memory_set::handler::{FrameAllocator, MemoryHandler};
|
||||||
|
use rcore_memory::memory_set::MemoryAttr;
|
||||||
|
use rcore_memory::paging::PageTable;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct RvmPageTableHandlerDelay<T: FrameAllocator> {
|
||||||
|
guest_start_paddr: GuestPhysAddr,
|
||||||
|
host_start_vaddr: HostVirtAddr,
|
||||||
|
gpm: Arc<DefaultGuestPhysMemorySet>,
|
||||||
|
allocator: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: FrameAllocator> RvmPageTableHandlerDelay<T> {
|
||||||
|
pub fn new(
|
||||||
|
guest_start_paddr: GuestPhysAddr,
|
||||||
|
host_start_vaddr: HostVirtAddr,
|
||||||
|
gpm: Arc<DefaultGuestPhysMemorySet>,
|
||||||
|
allocator: T,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
guest_start_paddr,
|
||||||
|
host_start_vaddr,
|
||||||
|
gpm,
|
||||||
|
allocator,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: FrameAllocator> MemoryHandler for RvmPageTableHandlerDelay<T> {
|
||||||
|
fn box_clone(&self) -> Box<dyn MemoryHandler> {
|
||||||
|
Box::new(self.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn map(&self, pt: &mut dyn PageTable, addr: HostVirtAddr, attr: &MemoryAttr) {
|
||||||
|
let entry = pt.map(addr, 0);
|
||||||
|
entry.set_present(false);
|
||||||
|
attr.apply(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unmap(&self, pt: &mut dyn PageTable, addr: HostVirtAddr) {
|
||||||
|
let entry = pt.get_entry(addr).expect("failed to get entry");
|
||||||
|
// PageTable::unmap requires page to be present
|
||||||
|
entry.set_present(true);
|
||||||
|
pt.unmap(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clone_map(
|
||||||
|
&self,
|
||||||
|
pt: &mut dyn PageTable,
|
||||||
|
src_pt: &mut dyn PageTable,
|
||||||
|
addr: HostVirtAddr,
|
||||||
|
attr: &MemoryAttr,
|
||||||
|
) {
|
||||||
|
let entry = src_pt.get_entry(addr).expect("failed to get entry");
|
||||||
|
if entry.present() {
|
||||||
|
// eager map and copy data
|
||||||
|
let data = src_pt.get_page_slice_mut(addr);
|
||||||
|
let target = self.allocator.alloc().expect("failed to alloc frame");
|
||||||
|
let entry = pt.map(addr, target);
|
||||||
|
attr.apply(entry);
|
||||||
|
pt.get_page_slice_mut(addr).copy_from_slice(data);
|
||||||
|
} else {
|
||||||
|
// delay map
|
||||||
|
self.map(pt, addr, attr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_page_fault(&self, pt: &mut dyn PageTable, addr: HostVirtAddr) -> bool {
|
||||||
|
let entry = pt.get_entry(addr).expect("failed to get entry");
|
||||||
|
if entry.present() {
|
||||||
|
// not a delay case
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let guest_paddr = addr - self.host_start_vaddr + self.guest_start_paddr;
|
||||||
|
let mut rvm_pt = self.gpm.rvm_page_table.lock();
|
||||||
|
let mut target = rvm_pt.query(guest_paddr).unwrap_or(0);
|
||||||
|
if target == 0 {
|
||||||
|
target = self.allocator.alloc().expect("failed to alloc frame");
|
||||||
|
}
|
||||||
|
rvm_pt
|
||||||
|
.map(guest_paddr, target, GuestMemoryAttr::default())
|
||||||
|
.expect("failed to create GPA -> HPA mapping");
|
||||||
|
|
||||||
|
entry.set_target(target);
|
||||||
|
entry.set_present(true);
|
||||||
|
entry.update();
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
55
kernel/src/rvm/mod.rs
Normal file
55
kernel/src/rvm/mod.rs
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
//! Implement hypervisor using rvm crate
|
||||||
|
|
||||||
|
#![deny(non_upper_case_globals)]
|
||||||
|
#![deny(dead_code)]
|
||||||
|
#![deny(unused_mut)]
|
||||||
|
#![deny(unused_variables)]
|
||||||
|
#![deny(unused_imports)]
|
||||||
|
|
||||||
|
use rcore_fs::vfs::FsError;
|
||||||
|
use rvm::RvmError;
|
||||||
|
|
||||||
|
mod inode;
|
||||||
|
mod memory;
|
||||||
|
mod structs;
|
||||||
|
|
||||||
|
pub use inode::RvmINode;
|
||||||
|
|
||||||
|
fn into_fs_error(e: RvmError) -> FsError {
|
||||||
|
match e {
|
||||||
|
RvmError::Internal => FsError::DeviceError,
|
||||||
|
RvmError::NotSupported => FsError::NotSupported,
|
||||||
|
RvmError::NoMemory => FsError::NoDeviceSpace,
|
||||||
|
RvmError::InvalidParam => FsError::InvalidParam,
|
||||||
|
RvmError::OutOfRange => FsError::InvalidParam,
|
||||||
|
RvmError::BadState => FsError::DeviceError,
|
||||||
|
RvmError::NotFound => FsError::InvalidParam,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod rvm_extern_fn {
|
||||||
|
use crate::memory::{alloc_frame, dealloc_frame, phys_to_virt};
|
||||||
|
#[rvm::extern_fn(alloc_frame)]
|
||||||
|
fn rvm_alloc_frame() -> Option<usize> {
|
||||||
|
alloc_frame()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rvm::extern_fn(dealloc_frame)]
|
||||||
|
fn rvm_dealloc_frame(paddr: usize) {
|
||||||
|
dealloc_frame(paddr)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rvm::extern_fn(phys_to_virt)]
|
||||||
|
fn rvm_phys_to_virt(paddr: usize) -> usize {
|
||||||
|
phys_to_virt(paddr)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
#[rvm::extern_fn(x86_all_traps_handler_addr)]
|
||||||
|
unsafe fn rvm_x86_all_traps_handler_addr() -> usize {
|
||||||
|
extern "C" {
|
||||||
|
fn __alltraps();
|
||||||
|
}
|
||||||
|
__alltraps as usize
|
||||||
|
}
|
||||||
|
}
|
54
kernel/src/rvm/structs.rs
Normal file
54
kernel/src/rvm/structs.rs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
//! Wrappers of rvm::Guest and rvm::Vcpu
|
||||||
|
|
||||||
|
use alloc::sync::Arc;
|
||||||
|
use spin::Mutex;
|
||||||
|
|
||||||
|
use rcore_memory::{memory_set::MemoryAttr, PAGE_SIZE};
|
||||||
|
use rvm::{DefaultGuestPhysMemorySet, GuestPhysAddr, HostVirtAddr, RvmResult};
|
||||||
|
use rvm::{Guest as GuestInner, Vcpu as VcpuInner};
|
||||||
|
|
||||||
|
use super::memory::RvmPageTableHandlerDelay;
|
||||||
|
use crate::memory::GlobalFrameAlloc;
|
||||||
|
|
||||||
|
pub(super) struct Guest {
|
||||||
|
gpm: Arc<DefaultGuestPhysMemorySet>,
|
||||||
|
pub(super) inner: Arc<GuestInner>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) struct Vcpu {
|
||||||
|
pub(super) inner: Mutex<VcpuInner>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Guest {
|
||||||
|
pub fn new() -> RvmResult<Self> {
|
||||||
|
let gpm = DefaultGuestPhysMemorySet::new();
|
||||||
|
Ok(Self {
|
||||||
|
inner: GuestInner::new(gpm.clone())?,
|
||||||
|
gpm,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_memory_region(&self, gpaddr: GuestPhysAddr, size: usize) -> RvmResult<HostVirtAddr> {
|
||||||
|
self.inner.add_memory_region(gpaddr, size, None)?;
|
||||||
|
let thread = crate::process::current_thread().unwrap();
|
||||||
|
let hvaddr = thread.vm.lock().find_free_area(PAGE_SIZE, size);
|
||||||
|
let handler =
|
||||||
|
RvmPageTableHandlerDelay::new(gpaddr, hvaddr, self.gpm.clone(), GlobalFrameAlloc);
|
||||||
|
thread.vm.lock().push(
|
||||||
|
hvaddr,
|
||||||
|
hvaddr + size,
|
||||||
|
MemoryAttr::default().user().writable(),
|
||||||
|
handler,
|
||||||
|
"rvm_guest_physical",
|
||||||
|
);
|
||||||
|
Ok(hvaddr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Vcpu {
|
||||||
|
pub fn new(entry: u64, guest: Arc<GuestInner>) -> RvmResult<Self> {
|
||||||
|
Ok(Self {
|
||||||
|
inner: Mutex::new(VcpuInner::new(entry, guest)?),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
2
user
2
user
@ -1 +1 @@
|
|||||||
Subproject commit 63342746297b9694676c82a716601d736ebab1a1
|
Subproject commit 94620bd696ac61b40129d845671cde83001fdf61
|
Loading…
Reference in New Issue
Block a user