AxVCpu: Virtual CPU interface and wrapper for ArceOS.

  • axvcpu 提供 CPU 虚拟化支持
    • 高度依赖于架构
    • 存储不同架构的异常上下文框架
    • 基本调度项
    • 特定架构的 vCPU 实现需要被分离到独立的 crate 中:
#![allow(unused)]
fn main() {
/// A trait for architecture-specific vcpu.
///
/// This trait is an abstraction for virtual CPUs of different architectures.
pub trait AxArchVCpu: Sized {
    /// The configuration for creating a new [`AxArchVCpu`]. Used by [`AxArchVCpu::new`].
    type CreateConfig;
    /// The configuration for setting up a created [`AxArchVCpu`]. Used by [`AxArchVCpu::setup`].
    type SetupConfig;

    /// Create a new `AxArchVCpu`.
    fn new(config: Self::CreateConfig) -> AxResult<Self>;

    /// Set the entry point of the vcpu.
    ///
    /// It's guaranteed that this function is called only once, before [`AxArchVCpu::setup`] being called.
    fn set_entry(&mut self, entry: GuestPhysAddr) -> AxResult;

    /// Set the EPT root of the vcpu.
    ///
    /// It's guaranteed that this function is called only once, before [`AxArchVCpu::setup`] being called.
    fn set_ept_root(&mut self, ept_root: HostPhysAddr) -> AxResult;

    /// Setup the vcpu.
    ///
    /// It's guaranteed that this function is called only once, after [`AxArchVCpu::set_entry`] and [`AxArchVCpu::set_ept_root`] being called.
    fn setup(&mut self, config: Self::SetupConfig) -> AxResult;

    /// Run the vcpu until a vm-exit occurs.
    fn run(&mut self) -> AxResult<AxVCpuExitReason>;

    /// Bind the vcpu to the current physical CPU.
    fn bind(&mut self) -> AxResult;

    /// Unbind the vcpu from the current physical CPU.
    fn unbind(&mut self) -> AxResult;

    /// Set the value of a general-purpose register according to the given index.
    fn set_gpr(&mut self, reg: usize, val: usize);
}
```<style>
  .scroll-to-top {
    font-size: 2.5rem;
    width: 3.2rem;
    height: 3.2rem;
    display: none;
    align-items: center;
    justify-content: center;
    position: fixed;
    padding: 0.75rem;
    bottom: 4rem;
    right: calc(1.25rem + 90px + var(--page-padding));
    z-index: 999;
    cursor: pointer;
    border: none;
    color: var(--bg);
    background: var(--fg);
    border-radius: 50%;
  }
  .scroll-to-top.hidden {
    display: none;
  }
  .scroll-to-top i {
    transform: translateY(-2px);
  }
  @media (min-width: 1080px) {
    .scroll-to-top {
      display: flex;
    }
  }
</style>
<button type="button" aria-label="scroll-to-top" class="scroll-to-top hidden" onclick="scrollToTop()">
  <i class="fa fa-angle-up"></i>
</button>
<script>
  const scrollToTop = () => window.scroll({ top: 0, behavior: "smooth" });
  window.addEventListener("scroll", () => {
    const button = document.querySelector(".scroll-to-top");
    button.classList.toggle("hidden", window.scrollY < 200);
  });
</script>
<style>
  .announcement-banner {
    z-index: 150;
    color: var(--fg);
    position: relative;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    margin: 0;
    padding: 1rem 3.5rem;
    background: repeating-linear-gradient(
      45deg,
      var(--site-announcement-bar-stripe-color1),
      var(--site-announcement-bar-stripe-color1) 20px,
      var(--site-announcement-bar-stripe-color2) 10px,
      var(--site-announcement-bar-stripe-color2) 40px
    );
  }
  .announcement-banner {
    --site-announcement-bar-stripe-color1: #e5e7eb;
    --site-announcement-bar-stripe-color2: #d1d5db;
  }
  .announcement-banner[data-theme="ocean"] {
    --site-announcement-bar-stripe-color1: #86b2f9;
    --site-announcement-bar-stripe-color2: #7298ea;
  }
  .announcement-banner[data-theme="forest"] {
    --site-announcement-bar-stripe-color1: #97f5d6;
    --site-announcement-bar-stripe-color2: #6de0bf;
  }
  .announcement-banner[data-theme="lava"] {
    --site-announcement-bar-stripe-color1: #fea3a3;
    --site-announcement-bar-stripe-color2: #e57e7e;
  }
  html:is(.navy, .coal, .ayu) .announcement-banner {
    --site-announcement-bar-stripe-color1: #1f2937;
    --site-announcement-bar-stripe-color2: #111827;
  }
  html:is(.navy, .coal, .ayu) .announcement-banner[data-theme="ocean"] {
    --site-announcement-bar-stripe-color1: #2563eb;
    --site-announcement-bar-stripe-color2: #1d4ed8;
  }
  html:is(.navy, .coal, .ayu) .announcement-banner[data-theme="forest"] {
    --site-announcement-bar-stripe-color1: #22d3a5;
    --site-announcement-bar-stripe-color2: #0fbf8f;
  }
  html:is(.navy, .coal, .ayu) .announcement-banner[data-theme="lava"] {
    --site-announcement-bar-stripe-color1: #f87171;
    --site-announcement-bar-stripe-color2: #ef4444;
  }
  .announcement-banner p {
    width: 100%;
    margin: 0;
    padding: 0;
    overflow: hidden;
    text-align: center;
    white-space: nowrap;
    text-overflow: ellipsis;
    text-wrap: balance;
  }
  .announcement-banner button {
    top: 50%;
    right: 1rem;
    position: absolute;
    transform: translateY(-50%);
    width: 3rem;
    height: 3rem;
    cursor: pointer !important;
    border: none;
    font-weight: 900;
    border-radius: 50%;
    background-color: transparent;
  }
</style>
<div style="display: none" data-id="0.2.11" class="announcement-banner" data-theme="default">
  <p><em>正在逐步完善中。。。</em></p>

  <button type="button">X</button>
</div>
<script>
  (() => {
    const banner = document.querySelector(".announcement-banner");
    const id = banner.getAttribute("data-id");
    const message = banner.querySelector("p").textContent;
    const localData = JSON.parse(localStorage.getItem("mdbook-announcement-banner"));
    if (!localData || localData.id !== id || localData.hide !== true) {
      banner.style.display = "flex";
      const page = document.querySelector(".page");
      page.parentNode.insertBefore(banner, page);
      banner.querySelector("button").addEventListener("click", () => {
        banner.remove();
        localStorage.setItem("mdbook-announcement-banner", JSON.stringify({ id, hide: true, message }));
      });
    }
  })();
</script>
<style>
  .giscus {
    margin-top: 6rem;
  }
</style>
<script
  src="https://giscus.app/client.js"
  data-repo="arceos-hypervisor/doc"
  data-repo-id="R_kgDOLMHfvQ"
  data-category="Comments"
  data-category-id="DIC_kwDOLMHfvc4CoqAB"
  data-mapping="title"
  data-strict="0"
  data-reactions-enabled="1"
  data-emit-metadata="0"
  data-input-position="bottom"
  data-theme="light"
  data-lang="zh-CN"
  data-loading="eager"
  crossorigin="anonymous"
  async
></script>
<script>
  (() => {
    const giscusScript = document.querySelector("script[data-repo][data-repo-id]");
    if (giscusScript?.getAttribute("data-theme") !== "book") return;
    const mapTheme = (theme) => (theme === "light" || theme === "rust" ? "light" : "dark");
    const bookTheme = localStorage.getItem("mdbook-theme") || html.getAttribute("class");
    giscusScript.setAttribute("data-theme", mapTheme(bookTheme));
    document.querySelectorAll("button[role='menuitem'].theme").forEach((btn) => {
      btn.addEventListener("click", (event) => {
        theme = mapTheme(event.target.id);
        const iframe = document.querySelector("iframe.giscus-frame");
        if (iframe) iframe.contentWindow.postMessage({ giscus: { setConfig: { theme } } }, "*");
      });
    });
  })();
</script>
<style>
  footer {
    text-align: center;
    text-wrap: balance;
    margin-top: 5rem;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
  }
  footer p {
    margin: 0;
  }
</style>
<footer><p>Copyright © 2025 • Created by ArceOS Team</p>
</footer>
}