From nobody Sun Feb 8 10:53:24 2026
Delivered-To: importer@patchew.org
Received-SPF: pass (zohomail.com: domain of redhat.com designates
207.211.31.120 as permitted sender) client-ip=207.211.31.120;
envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-1.mimecast.com;
Authentication-Results: mx.zohomail.com;
dkim=pass;
spf=pass (zohomail.com: domain of redhat.com designates 207.211.31.120 as
permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com;
dmarc=pass(p=none dis=none) header.from=redhat.com
ARC-Seal: i=1; a=rsa-sha256; t=1574434073; cv=none;
d=zohomail.com; s=zohoarc;
b=MGYR7NBn2E9WokyXxaZweOMdbnrCy0dgP161cNbnixsqSlnvb/1Ex4rdAKTUnq6NKJVVgvNWvg4mjNY6ga7RL+p9tpzhhdr2zYLR35Ac0zYB+AWQAnIqkoR9BkMhRjqktFBN8iwrd6D66mJ5m8NqhjB7bGUsIcBQa2zlT3thkKY=
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com;
s=zohoarc;
t=1574434073;
h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To;
bh=Ptrjt9X25JjUTDH8iyaRmVz89LOPgkYuBTGivxPxzu4=;
b=NFOdiZZ7Vgyljqu+JfQwaTuMKO+RrKKyxaORdHmN2BigCPlFuW2Uf/w1rMP4uYl5TDtcrhWGZkBHer7911DgyPtMrekKfkE5XFxYQ6d3PBqhlkU5UEhbyV/bnsNcYejz6MzlfWX4nQEAgxPsR4/gbHJxsxkZApVmOKBaCZQovRw=
ARC-Authentication-Results: i=1; mx.zohomail.com;
dkim=pass;
spf=pass (zohomail.com: domain of redhat.com designates 207.211.31.120 as
permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com;
dmarc=pass header.from=
- Storage encryption in modern public cloud computing is a common pr=
actice.
- However, from the point of view of a user of these cloud workloads=
, a
- significant amount of trust needs to be put in the cloud platform =
security as
- well as integrity (was the hypervisor tampered?). For this reason =
there's ever
- rising demand for securing data in use, i.e. memory encryption.
- One of the solutions addressing this matter is AMD SEV.
-
- SEV (Secure Encrypted Virtualization) is a feature extension of AM=
D's SME (Secure
- Memory Encryption) intended for KVM virtual machines which is supp=
orted
- primarily on AMD's EPYC CPU line. In contrast to SME, SEV uses a u=
nique memory encryption
- key for each VM. The whole encryption of memory pages is completel=
y transparent
- to the hypervisor and happens inside dedicated hardware in the on-=
die memory controller.
- Each controller includes a high-performance Advanced Encryption St=
andard
- (AES) engine that encrypts data when it is written to DRAM and dec=
rypts it
- when read.
-
- For more details about the technology itself, you can visit
- AMD's developer portal.
-
- Before VMs can make use of the SEV feature you need to make sure=
your
- AMD CPU does support SEV. You can check whether SEV is among the=
CPU
- flags with:
-
- Next step is to enable SEV in the kernel, because it is disabled=
by default.
- This is done by putting the following onto the kernel command li=
ne:
-
- To make the changes persistent, append the above to the variable=
holding
- parameters of the kernel command line in
-
-
- After rebooting the host, you should see SEV being enabled in th=
e kernel:
-
- Note: All of the commands bellow need to be run with root privi=
leges.
-
- First make sure you have the following packages in the specified=
versions:
-
- To confirm that the virtualization stack supports SEV, run the f=
ollowing:
-
- Note that if libvirt was already installed and libvirtd running =
before enabling SEV in the kernel followed by the host reboot you need to f=
orce libvirtd
- to re-probe both the host and QEMU capabilities. First stop libv=
irtd:
-
- Now you need to clean the capabilities cache:
-
- If you now restart libvirtd, it will re-probe the capabilities a=
nd if
- you now run:
-
- SEV should be listed as supported. If you still see:
-
- it means one of two things:
- Launch security with AMD SEV
-
-
-
-
AMD SEV
- Enabling SEV on the host
-
-$ cat /proc/cpuinfo | grep sev
-...
-sme ssbd sev ibpb
-
-
-mem_encrypt=3Don kvm_amd.sev=3D1
-
-
- /etc/default/grub to preserve SEV settings across r=
eboots
-
-$ cat /etc/default/grub
-...
-GRUB_CMDLINE_LINUX=3D"... mem_encrypt=3Don kvm_amd.sev=3D1"
-$ grub2-mkconfig -o /boot/efi/EFI/<distro>/grub.cfg
-
- mem_encrypt=3Don turns on the SME memory encryption f=
eature on
- the host which protects against the physical attack on the hypervi=
sor
- memory. The kvm_amd.sev parameter actually enables SE=
V in
- the kvm module. It can be set on the command line alongside
- mem_encrypt like shown above, or it can be put into a
- module config under /etc/modprobe.d/
-
-$ cat /etc/modprobe.d/sev.conf
-options kvm_amd sev=3D1
-
-
-
-$ cat /sys/module/kvm_amd/parameters/sev
-1
-
-
- Checking SEV support in the virt stack
-
-
-
-# virsh domcapabilities
-<domainCapabilities>
-...
- <features>
- ...
- <sev supported=3D'yes'>
- <cbitpos>47</cbitpos>
- <reducedPhysBits>1</reducedPhysBits>
- </sev>
- ...
- </features>
-</domainCapabilities>
-
-# systemctl stop libvirtd.service
-
-
-
-# rm -f /var/cache/libvirt/qemu/capabilities/*
-
-
-
-# virsh domcapabilities
-
-
-
-<sev supported=3D'no'/>
-
-
-
-
- 'Permission denied' on /dev/sev beca=
use
- of the default permissions on the character device which preve=
nted
- QEMU from opening it during capabilities probing - you can eit=
her
- manually tweak the permissions so that QEMU has access to it or
- preferably install libvirt 5.1.0 or higher
-
- SEV is enabled in the XML by specifying the
- <=
;launchSecurity> element. However, specifying launchSecurity<=
/code> isn't
- enough to boot an SEV VM. Further configuration requirements are d=
iscussed
- below.
-
- Even though both Q35 and legacy PC machine types (for PC see also - "virtio") can be used with SEV, usage of the legacy PC machine t= ype is - strongly discouraged, since depending on how your OVMF package w= as - built (e.g. including features like SecureBoot or SMM) Q35 may e= ven be - required. -
- --... -<os> - <type arch=3D'x86_64' machine=3D'pc-q35-3.0'>hvm</type> - ... -</os> -...- -
-... -<os> - <type arch=3D'x86_64' machine=3D'pc-i440fx-3.0'>hvm</type> - ... -</os> -... -- -
- SEV is only going to work with OVMF (UEFI), so you'll need to po= int libvirt to - the correct OVMF binary. -
--... -<os> - <type arch=3D'x86_64' machine=3D'pc-q35-3.0'>hvm</type> - <loader readonly=3D'yes' type=3D'pflash'>/usr/share/edk2/ovmf/OVMF= _CODE.fd</loader> -</os> -...- -
- Internally, SEV expects that the encrypted memory pages won't be=
swapped out or move
- around so the VM memory needs to be pinned in physical RAM which=
will be
- handled by QEMU. Apart from that, certain memory regions allocat=
ed by QEMU
- itself (UEFI pflash, device ROMs, video RAM, etc.) have to be en=
crypted as
- well. This causes a conflict in how libvirt tries to protect the=
host.
- By default, libvirt enforces a memory hard limit on each VM's cg=
roup in order
- to protect the host from malicious QEMU to allocate and lock all=
the available
- memory. This limit corresponds to the total memory allocation fo=
r the VM given
- by <currentMemory> element. However, trying t=
o account for the additional
- memory regions QEMU allocates when calculating the limit in an a=
utomated manner
- is non-deterministic. One way to resolve this is to set the hard=
limit manually.
-
-
- Note: Figuring out the right number so that your guest boots and= isn't killed is - challenging, but 256MiB extra memory over the total guest RAM sh= ould suffice for - most workloads and may serve as a good starting point. - - For example, a domain with 4GB memory with a 256MiB extra hard l= imit would look - like this: -
- - --# virsh edit <domain> -<domain> - ... - <currentMemory unit=3D'KiB'>4194304</currentMemory> - <memtune> - <hard_limit unit=3D'KiB'>4456448</hard_limit> - </memtune> - ... -</domain>-
- There's another, preferred method of taking care of the limits by
- using the<memoryBacking> element along with t=
he
- <locked/> subelement:
-
-<domain> - ... - <memoryBacking> - <locked/> - </memoryBacking> - ... -</domain>- -
- What that does is that it tells libvirt not to force any hard li=
mit (well,
- unlimited) upon the VM cgroup. The obvious advantage is that one=
doesn't need
- to determine the hard limit for every single SEV-enabled VM. How=
ever, there is
- a significant security-related drawback to this approach. Since =
no hard limit
- is applied, a malicious QEMU could perform a DoS attack by locki=
ng all of the
- host's available memory. The way to avoid this issue and to prot=
ect the host is
- to enforce a bigger hard limit on the master cgroup containing a=
ll of the VMs
- - on systemd this is machine.slice.
-
-# systemctl set-property machine.slice MemoryHigh=3D<value>- -
- To put even stricter measures in place which would involve the O= OM killer, use -
-# systemctl set-property machine.slice MemoryMax=3D<value>- instead. Alternatively, you can create a systemd config (don't f= orget - to reload systemd configuration in this case): -
-# cat << EOF > /etc/systemd/system.control/machine.slice.d/90-Mem= oryMax.conf -MemoryMax=3D<value> -EOF- The trade-off to keep in mind with the second approach is that t= he VMs - can still perform DoS on each other. - - -
- In order to make virtio devices work, we need to enable emulated= IOMMU - on the devices so that virtual DMA can work. -
- --# virsh edit <domain> -<domain> - ... - <controller type=3D'virtio-serial' index=3D'0'> - <driver iommu=3D'on'/> - </controller> - <controller type=3D'scsi' index=3D'0' model=3D'virtio-scsi'> - <driver iommu=3D'on'/> - </controller> - ... - <memballoon model=3D'virtio'> - <driver iommu=3D'on'/> - </memballoon> - <rng model=3D'virtio'> - <backend model=3D'random'>/dev/urandom</backend> - <driver iommu=3D'on'/> - </rng> - ... -<domain>- -
- If you for some reason want to use the legacy PC machine type, fur= ther changes - to the virtio - configuration is required, because SEV will not work with Virtio &= lt;1.0. In - libvirt, this is handled by using the virtio-non-transitional devi= ce model - (libvirt >=3D 5.2.0 required). - -
- Note: some devices like video devices don't - support non-transitional model, which means that virtio GPU cann= ot be used. -
- - --<domain> - ... - <devices> - ... - <memballoon model=3D'virtio-non-transitional'> - <driver iommu=3D'on'/> - </memballoon> - </devices> - ... -</domain>- -
- After making the necessary adjustments discussed in - Configuration, the VM should now bo= ot - successfully with SEV enabled. You can then verify that the guest = has - SEV enabled by running: -
- --# dmesg | grep -i sev -AMD Secure Encrypted Virtualization (SEV) active- -
- Currently, the boot disk cannot be of type virtio-blk, instead, vi=
rtio-scsi
- needs to be used if virtio is desired. This limitation is expected=
to be lifted
- with future releases of kernel (the kernel used at the time of wri=
ting the
- article is 5.0.14).
- If you still cannot start an SEV VM, it could be because of wrong =
SELinux label on the /dev/sev device with selinux-policy <3=
.14.2.40 which prevents QEMU from touching the device. This can be resolved=
by upgrading the package, tuning the selinux policy rules manually to allo=
w svirt_t to access the device (see audit2allow on how to do t=
hat) or putting SELinux into permissive mode (discouraged).
-
-<domain type=3D'kvm'> - <name>sev-dummy</name> - <memory unit=3D'KiB'>4194304</memory> - <currentMemory unit=3D'KiB'>4194304</currentMemory> - <memoryBacking> - <locked/> - </memoryBacking> - <vcpu placement=3D'static'>4</vcpu> - <os> - <type arch=3D'x86_64' machine=3D'pc-q35-3.0'>hvm</type> - <loader readonly=3D'yes' type=3D'pflash'>/usr/share/edk2/ovmf/OV= MF_CODE.fd</loader> - <nvram>/var/lib/libvirt/qemu/nvram/sev-dummy_VARS.fd</nvram&g= t; - </os> - <features> - <acpi/> - <apic/> - <vmport state=3D'off'/> - </features> - <cpu mode=3D'host-model' check=3D'partial'> - <model fallback=3D'allow'/> - </cpu> - <clock offset=3D'utc'> - <timer name=3D'rtc' tickpolicy=3D'catchup'/> - <timer name=3D'pit' tickpolicy=3D'delay'/> - <timer name=3D'hpet' present=3D'no'/> - </clock> - <on_poweroff>destroy</on_poweroff> - <on_reboot>restart</on_reboot> - <on_crash>destroy</on_crash> - <pm> - <suspend-to-mem enabled=3D'no'/> - <suspend-to-disk enabled=3D'no'/> - </pm> - <devices> - <emulator>/usr/bin/qemu-kvm</emulator> - <disk type=3D'file' device=3D'disk'> - <driver name=3D'qemu' type=3D'qcow2'/> - <source file=3D'/var/lib/libvirt/images/sev-dummy.qcow2'/> - <target dev=3D'sda' bus=3D'scsi'/> - <boot order=3D'1'/> - </disk> - <controller type=3D'virtio-serial' index=3D'0'> - <driver iommu=3D'on'/> - </controller> - <controller type=3D'scsi' index=3D'0' model=3D'virtio-scsi'> - <driver iommu=3D'on'/> - </controller> - <interface type=3D'network'> - <mac address=3D'52:54:00:cc:56:90'/> - <source network=3D'default'/> - <model type=3D'virtio'/> - <driver iommu=3D'on'/> - </interface> - <graphics type=3D'spice' autoport=3D'yes'> - <listen type=3D'address'/> - <gl enable=3D'no'/> - </graphics> - <video> - <model type=3D'qxl'/> - </video> - <memballoon model=3D'virtio'> - <driver iommu=3D'on'/> - </memballoon> - <rng model=3D'virtio'> - <driver iommu=3D'on'/> - </rng> - </devices> - <launchSecurity type=3D'sev'> - <cbitpos>47</cbitpos> - <reducedPhysBits>1</reducedPhysBits> - <policy>0x0003</policy> - </launchSecurity> -</domain>- -
-<domain type=3D'kvm'> - <name>sev-dummy-legacy</name> - <memory unit=3D'KiB'>4194304</memory> - <currentMemory unit=3D'KiB'>4194304</currentMemory> - <memtune> - <hard_limit unit=3D'KiB'>5242880</hard_limit> - </memtune> - <vcpu placement=3D'static'>4</vcpu> - <os> - <type arch=3D'x86_64' machine=3D'pc-i440fx-3.0'>hvm</type> - <loader readonly=3D'yes' type=3D'pflash'>/usr/share/edk2/ovmf/OV= MF_CODE.fd</loader> - <nvram>/var/lib/libvirt/qemu/nvram/sev-dummy_VARS.fd</nvram&g= t; - <boot dev=3D'hd'/> - </os> - <features> - <acpi/> - <apic/> - <vmport state=3D'off'/> - </features> - <cpu mode=3D'host-model' check=3D'partial'> - <model fallback=3D'allow'/> - </cpu> - <clock offset=3D'utc'> - <timer name=3D'rtc' tickpolicy=3D'catchup'/> - <timer name=3D'pit' tickpolicy=3D'delay'/> - <timer name=3D'hpet' present=3D'no'/> - </clock> - <on_poweroff>destroy</on_poweroff> - <on_reboot>restart</on_reboot> - <on_crash>destroy</on_crash> - <pm> - <suspend-to-mem enabled=3D'no'/> - <suspend-to-disk enabled=3D'no'/> - </pm> - <devices> - <emulator>/usr/bin/qemu-kvm</emulator> - <disk type=3D'file' device=3D'disk'> - <driver name=3D'qemu' type=3D'qcow2'/> - <source file=3D'/var/lib/libvirt/images/sev-dummy-seabios.qcow2'/= > - <target dev=3D'sda' bus=3D'sata'/> - </disk> - <interface type=3D'network'> - <mac address=3D'52:54:00:d8:96:c8'/> - <source network=3D'default'/> - <model type=3D'virtio-non-transitional'/> - </interface> - <serial type=3D'pty'> - <target type=3D'isa-serial' port=3D'0'> - <model name=3D'isa-serial'/> - </target> - </serial> - <console type=3D'pty'> - <target type=3D'serial' port=3D'0'/> - </console> - <input type=3D'tablet' bus=3D'usb'> - <address type=3D'usb' bus=3D'0' port=3D'1'/> - </input> - <input type=3D'mouse' bus=3D'ps2'/> - <input type=3D'keyboard' bus=3D'ps2'/> - <graphics type=3D'spice' autoport=3D'yes'> - <listen type=3D'address'/> - <gl enable=3D'no'/> - </graphics> - <video> - <model type=3D'qxl' ram=3D'65536' vram=3D'65536' vgamem=3D'16384'= heads=3D'1' primary=3D'yes'/> - </video> - <memballoon model=3D'virtio-non-transitional'> - <driver iommu=3D'on'/> - </memballoon> - <rng model=3D'virtio-non-transitional'> - <driver iommu=3D'on'/> - </rng> - </devices> - <launchSecurity type=3D'sev'> - <cbitpos>47</cbitpos> - <reducedPhysBits>1</reducedPhysBits> - <policy>0x0003</policy> - </launchSecurity> -</domain>- - diff --git a/docs/kbase/launch_security_sev.rst b/docs/kbase/launch_securit= y_sev.rst new file mode 100644 index 0000000000..4387ae64b0 --- /dev/null +++ b/docs/kbase/launch_security_sev.rst @@ -0,0 +1,529 @@ +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D +Launch security with AMD SEV +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D + +.. contents:: + +Storage encryption in modern public cloud computing is a common +practice. However, from the point of view of a user of these cloud +workloads, a significant amount of trust needs to be put in the cloud +platform security as well as integrity (was the hypervisor tampered?). +For this reason there's ever rising demand for securing data in use, +i.e. memory encryption. One of the solutions addressing this matter is +AMD SEV. + +AMD SEV +=3D=3D=3D=3D=3D=3D=3D + +SEV (Secure Encrypted Virtualization) is a feature extension of AMD's +SME (Secure Memory Encryption) intended for KVM virtual machines which +is supported primarily on AMD's EPYC CPU line. In contrast to SME, SEV +uses a unique memory encryption key for each VM. The whole encryption of +memory pages is completely transparent to the hypervisor and happens +inside dedicated hardware in the on-die memory controller. Each +controller includes a high-performance Advanced Encryption Standard +(AES) engine that encrypts data when it is written to DRAM and decrypts +it when read. For more details about the technology itself, you can +visit `AMD's developer portal