Files
server/usr/share/doc/qemu-system-common/system/i386/sgx.html
2026-01-07 20:52:11 +01:00

349 lines
22 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html class="writer-html5" lang="en" data-content_root="../../">
<head>
<meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Software Guard eXtensions (SGX) &mdash; QEMU Debian 1:8.2.2+ds-0ubuntu1.11 documentation</title>
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css?v=fa44fd50" />
<link rel="stylesheet" type="text/css" href="../../_static/css/theme.css?v=86f27845" />
<link rel="stylesheet" type="text/css" href="../../_static/theme_overrides.css?v=08e6c168" />
<link rel="shortcut icon" href="../../_static/qemu_32x32.png"/>
<script src="../../_static/jquery.js?v=8dae8fb0"></script>
<script src="../../_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
<script src="../../_static/documentation_options.js?v=802af9f6"></script>
<script src="../../_static/doctools.js?v=888ff710"></script>
<script src="../../_static/sphinx_highlight.js?v=dc90522c"></script>
<script src="../../_static/custom.js?v=2ab9f71d"></script>
<script src="../../_static/js/theme.js"></script>
<link rel="index" title="Index" href="../../genindex.html" />
<link rel="search" title="Search" href="../../search.html" />
<link rel="next" title="AMD Secure Encrypted Virtualization (SEV)" href="amd-memory-encryption.html" />
<link rel="prev" title="Paravirtualized KVM features" href="kvm-pv.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" style="background: #802400" >
<a href="../../index.html" class="icon icon-home">
QEMU
<img src="../../_static/qemu_128x128.png" class="logo" alt="Logo"/>
</a>
<div class="version">
8.2.2
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../../search.html" method="get">
<input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../../about/index.html">About QEMU</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../index.html">System Emulation</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="../introduction.html">Introduction</a></li>
<li class="toctree-l2"><a class="reference internal" href="../invocation.html">Invocation</a></li>
<li class="toctree-l2"><a class="reference internal" href="../device-emulation.html">Device Emulation</a></li>
<li class="toctree-l2"><a class="reference internal" href="../keys.html">Keys in the graphical frontends</a></li>
<li class="toctree-l2"><a class="reference internal" href="../mux-chardev.html">Keys in the character backend multiplexer</a></li>
<li class="toctree-l2"><a class="reference internal" href="../monitor.html">QEMU Monitor</a></li>
<li class="toctree-l2"><a class="reference internal" href="../images.html">Disk Images</a></li>
<li class="toctree-l2"><a class="reference internal" href="../virtio-net-failover.html">QEMU virtio-net standby (net_failover)</a></li>
<li class="toctree-l2"><a class="reference internal" href="../linuxboot.html">Direct Linux Boot</a></li>
<li class="toctree-l2"><a class="reference internal" href="../generic-loader.html">Generic Loader</a></li>
<li class="toctree-l2"><a class="reference internal" href="../guest-loader.html">Guest Loader</a></li>
<li class="toctree-l2"><a class="reference internal" href="../barrier.html">QEMU Barrier Client</a></li>
<li class="toctree-l2"><a class="reference internal" href="../vnc-security.html">VNC security</a></li>
<li class="toctree-l2"><a class="reference internal" href="../tls.html">TLS setup for network services</a></li>
<li class="toctree-l2"><a class="reference internal" href="../secrets.html">Providing secret data to QEMU</a></li>
<li class="toctree-l2"><a class="reference internal" href="../authz.html">Client authorization</a></li>
<li class="toctree-l2"><a class="reference internal" href="../gdb.html">GDB usage</a></li>
<li class="toctree-l2"><a class="reference internal" href="../replay.html">Record/replay</a></li>
<li class="toctree-l2"><a class="reference internal" href="../managed-startup.html">Managed start up options</a></li>
<li class="toctree-l2"><a class="reference internal" href="../bootindex.html">Managing device boot order with bootindex properties</a></li>
<li class="toctree-l2"><a class="reference internal" href="../cpu-hotplug.html">Virtual CPU hotplug</a></li>
<li class="toctree-l2"><a class="reference internal" href="../pr-manager.html">Persistent reservation managers</a></li>
<li class="toctree-l2 current"><a class="reference internal" href="../targets.html">QEMU System Emulator Targets</a><ul class="current">
<li class="toctree-l3"><a class="reference internal" href="../target-arm.html">Arm System emulator</a></li>
<li class="toctree-l3"><a class="reference internal" href="../target-avr.html">AVR System emulator</a></li>
<li class="toctree-l3"><a class="reference internal" href="../target-m68k.html">ColdFire System emulator</a></li>
<li class="toctree-l3"><a class="reference internal" href="../target-mips.html">MIPS System emulator</a></li>
<li class="toctree-l3"><a class="reference internal" href="../target-ppc.html">PowerPC System emulator</a></li>
<li class="toctree-l3"><a class="reference internal" href="../target-openrisc.html">OpenRISC System emulator</a></li>
<li class="toctree-l3"><a class="reference internal" href="../target-riscv.html">RISC-V System emulator</a></li>
<li class="toctree-l3"><a class="reference internal" href="../target-rx.html">RX System emulator</a></li>
<li class="toctree-l3"><a class="reference internal" href="../target-s390x.html">s390x System emulator</a></li>
<li class="toctree-l3"><a class="reference internal" href="../target-sparc.html">Sparc32 System emulator</a></li>
<li class="toctree-l3"><a class="reference internal" href="../target-sparc64.html">Sparc64 System emulator</a></li>
<li class="toctree-l3 current"><a class="reference internal" href="../target-i386.html">x86 System emulator</a><ul class="current">
<li class="toctree-l4"><a class="reference internal" href="../target-i386.html#board-specific-documentation">Board-specific documentation</a></li>
<li class="toctree-l4 current"><a class="reference internal" href="../target-i386.html#architectural-features">Architectural features</a></li>
<li class="toctree-l4"><a class="reference internal" href="../target-i386.html#os-requirements">OS requirements</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../target-xtensa.html">Xtensa System emulator</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../security.html">Security</a></li>
<li class="toctree-l2"><a class="reference internal" href="../multi-process.html">Multi-process QEMU</a></li>
<li class="toctree-l2"><a class="reference internal" href="../confidential-guest-support.html">Confidential Guest Support</a></li>
<li class="toctree-l2"><a class="reference internal" href="../vm-templating.html">QEMU VM templating</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../user/index.html">User Mode Emulation</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../tools/index.html">Tools</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../interop/index.html">System Emulation Management and Interoperability</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../specs/index.html">System Emulation Guest Hardware Specifications</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../devel/index.html">Developer Information</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" style="background: #802400" >
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../../index.html">QEMU</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="Page navigation">
<ul class="wy-breadcrumbs">
<li><a href="../../index.html" class="icon icon-home" aria-label="Home"></a></li>
<li class="breadcrumb-item"><a href="../index.html">System Emulation</a></li>
<li class="breadcrumb-item"><a href="../targets.html">QEMU System Emulator Targets</a></li>
<li class="breadcrumb-item"><a href="../target-i386.html">x86 System emulator</a></li>
<li class="breadcrumb-item active">Software Guard eXtensions (SGX)</li>
<li class="wy-breadcrumbs-aside">
<a href="https://gitlab.com/qemu-project/qemu/blob/master/docs/system/i386/sgx.rst" class="fa fa-gitlab"> Edit on GitLab</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<section id="software-guard-extensions-sgx">
<h1>Software Guard eXtensions (SGX)<a class="headerlink" href="#software-guard-extensions-sgx" title="Link to this heading"></a></h1>
<section id="overview">
<h2>Overview<a class="headerlink" href="#overview" title="Link to this heading"></a></h2>
<p>Intel Software Guard eXtensions (SGX) is a set of instructions and mechanisms
for memory accesses in order to provide security accesses for sensitive
applications and data. SGX allows an application to use its pariticular
address space as an <em>enclave</em>, which is a protected area provides confidentiality
and integrity even in the presence of privileged malware. Accesses to the
enclave memory area from any software not resident in the enclave are prevented,
including those from privileged software.</p>
</section>
<section id="virtual-sgx">
<h2>Virtual SGX<a class="headerlink" href="#virtual-sgx" title="Link to this heading"></a></h2>
<p>SGX feature is exposed to guest via SGX CPUID. Looking at SGX CPUID, we can
report the same CPUID info to guest as on host for most of SGX CPUID. With
reporting the same CPUID guest is able to use full capacity of SGX, and KVM
doesnt need to emulate those info.</p>
<p>The guests EPC base and size are determined by QEMU, and KVM needs QEMU to
notify such info to it before it can initialize SGX for guest.</p>
<section id="virtual-epc">
<h3>Virtual EPC<a class="headerlink" href="#virtual-epc" title="Link to this heading"></a></h3>
<p>By default, QEMU does not assign EPC to a VM, i.e. fully enabling SGX in a VM
requires explicit allocation of EPC to the VM. Similar to other specialized
memory types, e.g. hugetlbfs, EPC is exposed as a memory backend.</p>
<p>SGX EPC is enumerated through CPUID, i.e. EPC “devices” need to be realized
prior to realizing the vCPUs themselves, which occurs long before generic
devices are parsed and realized. This limitation means that EPC does not
require -maxmem as EPC is not treated as {cold,hot}plugged memory.</p>
<p>QEMU does not artificially restrict the number of EPC sections exposed to a
guest, e.g. QEMU will happily allow you to create 64 1M EPC sections. Be aware
that some kernels may not recognize all EPC sections, e.g. the Linux SGX driver
is hardwired to support only 8 EPC sections.</p>
<p>The following QEMU snippet creates two EPC sections, with 64M pre-allocated
to the VM and an additional 28M mapped but not allocated:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">-</span><span class="nb">object</span> <span class="n">memory</span><span class="o">-</span><span class="n">backend</span><span class="o">-</span><span class="n">epc</span><span class="p">,</span><span class="nb">id</span><span class="o">=</span><span class="n">mem1</span><span class="p">,</span><span class="n">size</span><span class="o">=</span><span class="mi">64</span><span class="n">M</span><span class="p">,</span><span class="n">prealloc</span><span class="o">=</span><span class="n">on</span> \
<span class="o">-</span><span class="nb">object</span> <span class="n">memory</span><span class="o">-</span><span class="n">backend</span><span class="o">-</span><span class="n">epc</span><span class="p">,</span><span class="nb">id</span><span class="o">=</span><span class="n">mem2</span><span class="p">,</span><span class="n">size</span><span class="o">=</span><span class="mi">28</span><span class="n">M</span> \
<span class="o">-</span><span class="n">M</span> <span class="n">sgx</span><span class="o">-</span><span class="n">epc</span><span class="mf">.0</span><span class="o">.</span><span class="n">memdev</span><span class="o">=</span><span class="n">mem1</span><span class="p">,</span><span class="n">sgx</span><span class="o">-</span><span class="n">epc</span><span class="mf">.1</span><span class="o">.</span><span class="n">memdev</span><span class="o">=</span><span class="n">mem2</span>
</pre></div>
</div>
<p>Note:</p>
<p>The size and location of the virtual EPC are far less restricted compared
to physical EPC. Because physical EPC is protected via range registers,
the size of the physical EPC must be a power of two (though software sees
a subset of the full EPC, e.g. 92M or 128M) and the EPC must be naturally
aligned. KVM SGXs virtual EPC is purely a software construct and only
requires the size and location to be page aligned. QEMU enforces the EPC
size is a multiple of 4k and will ensure the base of the EPC is 4k aligned.
To simplify the implementation, EPC is always located above 4g in the guest
physical address space.</p>
</section>
<section id="migration">
<h3>Migration<a class="headerlink" href="#migration" title="Link to this heading"></a></h3>
<p>QEMU/KVM doesnt prevent live migrating SGX VMs, although from hardwares
perspective, SGX doesnt support live migration, since both EPC and the SGX
key hierarchy are bound to the physical platform. However live migration
can be supported in the sense if guest software stack can support recreating
enclaves when it suffers sudden lose of EPC; and if guest enclaves can detect
SGX keys being changed, and handle gracefully. For instance, when ERESUME fails
with #PF.SGX, guest software can gracefully detect it and recreate enclaves;
and when enclave fails to unseal sensitive information from outside, it can
detect such error and sensitive information can be provisioned to it again.</p>
</section>
<section id="cpuid">
<h3>CPUID<a class="headerlink" href="#cpuid" title="Link to this heading"></a></h3>
<p>Due to its myriad dependencies, SGX is currently not listed as supported
in any of QEMUs built-in CPU configuration. To expose SGX (and SGX Launch
Control) to a guest, you must either use <code class="docutils literal notranslate"><span class="pre">-cpu</span> <span class="pre">host</span></code> to pass-through the
host CPU model, or explicitly enable SGX when using a built-in CPU model,
e.g. via <code class="docutils literal notranslate"><span class="pre">-cpu</span> <span class="pre">&lt;model&gt;,+sgx</span></code> or <code class="docutils literal notranslate"><span class="pre">-cpu</span> <span class="pre">&lt;model&gt;,+sgx,+sgxlc</span></code>.</p>
<p>All SGX sub-features enumerated through CPUID, e.g. SGX2, MISCSELECT,
ATTRIBUTES, etc… can be restricted via CPUID flags. Be aware that enforcing
restriction of MISCSELECT, ATTRIBUTES and XFRM requires intercepting ECREATE,
i.e. may marginally reduce SGX performance in the guest. All SGX sub-features
controlled via -cpu are prefixed with “sgx”, e.g.:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ qemu-system-x86_64 -cpu help | xargs printf &quot;%s\n&quot; | grep sgx
sgx
sgx-debug
sgx-encls-c
sgx-enclv
sgx-exinfo
sgx-kss
sgx-mode64
sgx-provisionkey
sgx-tokenkey
sgx1
sgx2
sgxlc
</pre></div>
</div>
<p>The following QEMU snippet passes through the host CPU but restricts access to
the provision and EINIT token keys:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">-</span><span class="n">cpu</span> <span class="n">host</span><span class="p">,</span><span class="o">-</span><span class="n">sgx</span><span class="o">-</span><span class="n">provisionkey</span><span class="p">,</span><span class="o">-</span><span class="n">sgx</span><span class="o">-</span><span class="n">tokenkey</span>
</pre></div>
</div>
<p>SGX sub-features cannot be emulated, i.e. sub-features that are not present
in hardware cannot be forced on via -cpu.</p>
</section>
<section id="virtualize-sgx-launch-control">
<h3>Virtualize SGX Launch Control<a class="headerlink" href="#virtualize-sgx-launch-control" title="Link to this heading"></a></h3>
<p>QEMU SGX support for Launch Control (LC) is passive, in the sense that it
does not actively change the LC configuration. QEMU SGX provides the user
the ability to set/clear the CPUID flag (and by extension the associated
IA32_FEATURE_CONTROL MSR bit in fw_cfg) and saves/restores the LE Hash MSRs
when getting/putting guest state, but QEMU does not add new controls to
directly modify the LC configuration. Similar to hardware behavior, locking
the LC configuration to a non-Intel value is left to guest firmware. Unlike
host bios setting for SGX launch control(LC), there is no special bios setting
for SGX guest by our design. If host is in locked mode, we can still allow
creating VM with SGX.</p>
</section>
<section id="feature-control">
<h3>Feature Control<a class="headerlink" href="#feature-control" title="Link to this heading"></a></h3>
<p>QEMU SGX updates the <code class="docutils literal notranslate"><span class="pre">etc/msr_feature_control</span></code> fw_cfg entry to set the SGX
(bit 18) and SGX LC (bit 17) flags based on their respective CPUID support,
i.e. existing guest firmware will automatically set SGX and SGX LC accordingly,
assuming said firmware supports fw_cfg.msr_feature_control.</p>
</section>
</section>
<section id="launching-a-guest">
<h2>Launching a guest<a class="headerlink" href="#launching-a-guest" title="Link to this heading"></a></h2>
<p>To launch a SGX guest:</p>
<pre class="literal-block">qemu-system-x86_64 \
-cpu host,+sgx-provisionkey \
-object memory-backend-epc,id=mem1,size=64M,prealloc=on \
-M sgx-epc.0.memdev=mem1,sgx-epc.0.node=0</pre>
<p>Utilizing SGX in the guest requires a kernel/OS with SGX support.
The support can be determined in guest by:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ grep sgx /proc/cpuinfo
</pre></div>
</div>
<p>and SGX epc info by:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ dmesg | grep sgx
[ 0.182807] sgx: EPC section 0x140000000-0x143ffffff
[ 0.183695] sgx: [Firmware Bug]: Unable to map EPC section to online node. Fallback to the NUMA node 0.
</pre></div>
</div>
<p>To launch a SGX numa guest:</p>
<pre class="literal-block">qemu-system-x86_64 \
-cpu host,+sgx-provisionkey \
-object memory-backend-ram,size=2G,host-nodes=0,policy=bind,id=node0 \
-object memory-backend-epc,id=mem0,size=64M,prealloc=on,host-nodes=0,policy=bind \
-numa node,nodeid=0,cpus=0-1,memdev=node0 \
-object memory-backend-ram,size=2G,host-nodes=1,policy=bind,id=node1 \
-object memory-backend-epc,id=mem1,size=28M,prealloc=on,host-nodes=1,policy=bind \
-numa node,nodeid=1,cpus=2-3,memdev=node1 \
-M sgx-epc.0.memdev=mem0,sgx-epc.0.node=0,sgx-epc.1.memdev=mem1,sgx-epc.1.node=1</pre>
<p>and SGX epc numa info by:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ dmesg | grep sgx
[ 0.369937] sgx: EPC section 0x180000000-0x183ffffff
[ 0.370259] sgx: EPC section 0x184000000-0x185bfffff
$ dmesg | grep SRAT
[ 0.009981] ACPI: SRAT: Node 0 PXM 0 [mem 0x180000000-0x183ffffff]
[ 0.009982] ACPI: SRAT: Node 1 PXM 1 [mem 0x184000000-0x185bfffff]
</pre></div>
</div>
</section>
<section id="references">
<h2>References<a class="headerlink" href="#references" title="Link to this heading"></a></h2>
<ul class="simple">
<li><p><a class="reference external" href="https://software.intel.com/sgx">SGX Homepage</a></p></li>
<li><p><a class="reference external" href="https://github.com/intel/linux-sgx.git">SGX SDK</a></p></li>
<li><p>SGX specification: Intel SDM Volume 3</p></li>
</ul>
</section>
</section>
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="kvm-pv.html" class="btn btn-neutral float-left" title="Paravirtualized KVM features" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="amd-memory-encryption.html" class="btn btn-neutral float-right" title="AMD Secure Encrypted Virtualization (SEV)" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>
<div role="contentinfo">
<p>&#169; Copyright 2025, The QEMU Project Developers.</p>
</div>
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
provided by <a href="https://readthedocs.org">Read the Docs</a>.
<!-- Empty para to force a blank line after "Built with Sphinx ..." -->
<p></p>
<p>This documentation is for QEMU version 8.2.2.</p>
<p><a href="../../about/license.html">QEMU and this manual are released under the
GNU General Public License, version 2.</a></p>
</footer>
</div>
</div>
</section>
</div>
<script>
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>