QEMU should define and implement the location & size of SMRAM, and the method to lock & unlock it. As far as I know, TCG already has some kind of support. (Only TCG.)
There's been at least one upstream discussion about this:
(Plus, messages in that thread reference other discussions.)
The current suggestion seems to be the 0xa0000-0xc0000 range, which I
think should be possible for i440fx as well.
However, the size of that range is only 128KB, and the SMM Core in edk2 needs at least 256KB - 4KB == 252KB.
(See SmmIplEntry() in "MdeModulePkg/Core/PiSmmCore/PiSmmIpl.c", and SmmInitializeMemoryServices() in "MdeModulePkg/Core/PiSmmCore/Pool.c".)
We might have to introduce something new under 4GB-2MB (ie. underneath the pflash chip(s)), but that will seriously complicate things for OVMF (messing with the memory layout is always a pain).
Alternatively, we might inquire on edk2-devel where the 252KB SMRAM requirement comes from. (The answer is probably that SMRAM is not only used for storing data, it hosts some privileged driver executables as well.)
So this is an even worse mess than I expected. I had an annoying feeling in the back of my mind, and after re-checking the following whitepaper, that annoyance seems to be justified:
A Tour Beyond BIOS:
Implementing UEFI Authenticated Variables in SMM with EDKII
In the overview section, it introduces the platform-independent, variable-related SMM drivers (all known to us). Then it says (emphasis mine):
This driver runs in SMM and expects to have another SMM driver, such as
the closed sourced SMM FVB (Firmware Volume Block) driver, in order to
write to SPI NOR from SMRAM. The PCH or other IOH is programmed such that
the write access to SPI NOR can only occur from SMM.
So today’s art includes SMM for isolated execution and volatile storage,
with SMM-based access control for writes to the SPI NOR.
Under Thread Model, it says
[...] software attacking where ring0 non-UEFI code can directly
modify the flash region containing the authenticated variables poses
Many platforms today use SMM and SPI NOR write trapping to have isolated,
access controlled usage of this persistent store.
The above has two implications.
First, in OVMF even the current pflash driver, OvmfPkg/QemuFlashFvbServicesRuntimeDxe/, has to be replaced.
Second, the pflash implementation in QEMU, hw/block/pflash_cfi01.c, needs to know (or needs to be able to know) about SMM, and reject writes unless in SMM. Perhaps this can be implemented with some well placed memory_region_*() calls.
> Second, the pflash implementation in QEMU, hw/block/pflash_cfi01.c, needs to
> know (or needs to be able to know) about SMM, and reject writes unless in SMM.
> Perhaps this can be implemented with some well placed memory_region_*() calls.
Luckily this was expected. The plan is to use Peter Maydell's MemTxAttrs patches to implement this.
I didn't know that QemuFlashFvbServicesRuntimeDxe had to be replaced (or at least an SMM variant of it has to be added), though in retrospect it's not too surprising.
Has verified it, the problem not exist.
Kernel version: 3.10.0-488.el7.x86_64
QEMU verison: qemu-img-rhev-2.6.0-14.el7.x86_64
OVMF Version: OVMF-20160608-3.git988715a.el7.noarch
/usr/libexec/qemu-kvm -name rhel7 \
-machine q35,accel=kvm,usb=off,vmport=off,smm=on \
-cpu SandyBridge \
-m 8192 \
-realtime mlock=off \
-smp 5 \
-uuid 1534fa42-4818-4493-9f67-eee5ba758385 \
-no-user-config -nodefaults \
-chardev socket,id=qmp_id_catch_monitor,path=/var/tmp/test1,server,nowait \
-mon chardev=qmp_id_catch_monitor,id=monitor,mode=control \
-boot menu=on,splash-time=12000 \
-vga qxl \
-monitor stdio \
-vnc 0:2 \
-netdev tap,id=hostnet10 \
-device virtio-net-pci,netdev=hostnet10,id=net10,mac=58:54:00:49:b2:5f \
-spice ipv4,port=5000,disable-ticketing \
-global ICH9-LPC.disable_s3=0 \
-drive file=/usr/share/OVMF/OVMF_CODE.secboot.fd,if=pflash,format=raw,readonly=on \
-drive file=/usr/share/OVMF/OVMF_Client_VARS.fd,if=pflash,format=raw \
-device ahci,id=ahci \
-global driver=cfi.pflash01,property=secure,value=on \
-drive file=/home/73test/img/bug_v_secure.qcow2,if=none,id=drive-ide-3,media=disk,format=qcow2,cache=none,aio=native \
-device ide-drive,drive=drive-ide-3,id=ide3,bus=ahci.0,bootindex=0 \
-drive file=/home/kvm_autotest_root/iso/linux/RHEL-7.2-20151030.0-Server-x86_64-dvd1.iso,if=none,cache=none,snapshot=off,aio=native,media=cdrom,id=cdrom2 \
-device ide-cd,drive=cdrom2,id=ide-cd2,bus=ahci.1,bootindex=2 \
-drive file=/usr/share/OVMF/UefiShell.iso,if=none,cache=none,snapshot=off,aio=native,media=cdrom,id=cdrom3 \
-device ide-cd,drive=cdrom3,id=ide-cd3,bus=ahci.2,bootindex=1 \
Refer to bug 1308678.
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.
For information on the advisory, and where to find the updated
files, follow the link below.
If the solution does not work for you, open a new bug report.