diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf
index c50709c..310d6a9 100644
--- a/OvmfPkg/OvmfPkgIa32.fdf
+++ b/OvmfPkg/OvmfPkgIa32.fdf
@@ -23,31 +23,51 @@
 #
 [Defines]
 !if $(TARGET) == RELEASE
 !ifndef $(FD_SIZE_2MB)
 DEFINE FD_SIZE_1MB=
 !endif
 !endif
 
+!ifdef $(SPLIT_VARSTORE)
+!ifdef $(FD_SIZE_1MB)
+[FD.NvVarStore]
+BaseAddress   = 0xFFF00000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
+SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize = 0x00100000
+Size          = 0x20000
+ErasePolarity = 1
+BlockSize     = 0x1000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareBlockSize
+NumBlocks     = 0x20
+!else
+[FD.NvVarStore]
+BaseAddress   = 0xFFE00000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
+SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize = 0x00200000
+Size          = 0x20000
+ErasePolarity = 1
+BlockSize     = 0x1000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareBlockSize
+NumBlocks     = 0x20
+!endif
+!else
 !ifdef $(FD_SIZE_1MB)
 [FD.OVMF]
 BaseAddress   = 0xFFF00000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
 Size          = 0x00100000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize
 ErasePolarity = 1
 BlockSize     = 0x1000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareBlockSize
 NumBlocks     = 0x100
 !else
 [FD.OVMF]
 BaseAddress   = 0xFFE00000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
 Size          = 0x00200000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize
 ErasePolarity = 1
 BlockSize     = 0x1000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareBlockSize
 NumBlocks     = 0x200
 !endif
+!endif
 
 0x00000000|0x0000e000
 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageVariableBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
 #NV_VARIABLE_STORE
 DATA = {
   ## This is the EFI_FIRMWARE_VOLUME_HEADER
   # ZeroVector []
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -106,30 +126,58 @@ DATA = {
   # WriteQueueSize: UINT64
   0xE0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 }
 
 0x00010000|0x00010000
 #NV_FTW_SPARE
 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
 
+!ifdef $(SPLIT_VARSTORE)
+!ifdef $(FD_SIZE_1MB)
+[FD.OVMF]
+BaseAddress   = 0xFFF20000
+Size          = 0x000E0000
+ErasePolarity = 1
+BlockSize     = 0x1000
+NumBlocks     = 0xE0
+
+0x00000000|0x000CC000
+FV = FVMAIN_COMPACT
+0x000CC000|0x14000
+FV = SECFV
+!else
+[FD.OVMF]
+BaseAddress   = 0xFFE20000
+Size          = 0x001E0000
+ErasePolarity = 1
+BlockSize     = 0x1000
+NumBlocks     = 0x1E0
+
+0x00000000|0x001AC000
+FV = FVMAIN_COMPACT
+0x001AC000|0x34000
+FV = SECFV
+!endif
+!else
 !ifdef $(FD_SIZE_1MB)
 0x00020000|0x000CC000
 FV = FVMAIN_COMPACT
 
 0x000EC000|0x14000
 FV = SECFV
 
 !else
 0x00020000|0x001AC000
 FV = FVMAIN_COMPACT
 
 0x001CC000|0x34000
 FV = SECFV
 !endif
+!endif
 
 ################################################################################
 
 [FD.MEMFD]
 BaseAddress   = 0x800000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfMemFvBase
 Size          = 0x800000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfMemFvSize
 ErasePolarity = 1
 BlockSize     = 0x10000
diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf
index d65f40f..8877a89 100644
--- a/OvmfPkg/OvmfPkgIa32X64.fdf
+++ b/OvmfPkg/OvmfPkgIa32X64.fdf
@@ -23,31 +23,51 @@
 #
 [Defines]
 !if $(TARGET) == RELEASE
 !ifndef $(FD_SIZE_2MB)
 DEFINE FD_SIZE_1MB=
 !endif
 !endif
 
+!ifdef $(SPLIT_VARSTORE)
+!ifdef $(FD_SIZE_1MB)
+[FD.NvVarStore]
+BaseAddress   = 0xFFF00000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
+SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize = 0x00100000
+Size          = 0x20000
+ErasePolarity = 1
+BlockSize     = 0x1000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareBlockSize
+NumBlocks     = 0x20
+!else
+[FD.NvVarStore]
+BaseAddress   = 0xFFE00000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
+SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize = 0x00200000
+Size          = 0x20000
+ErasePolarity = 1
+BlockSize     = 0x1000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareBlockSize
+NumBlocks     = 0x20
+!endif
+!else
 !ifdef $(FD_SIZE_1MB)
 [FD.OVMF]
 BaseAddress   = 0xFFF00000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
 Size          = 0x00100000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize
 ErasePolarity = 1
 BlockSize     = 0x1000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareBlockSize
 NumBlocks     = 0x100
 !else
 [FD.OVMF]
 BaseAddress   = 0xFFE00000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
 Size          = 0x00200000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize
 ErasePolarity = 1
 BlockSize     = 0x1000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareBlockSize
 NumBlocks     = 0x200
 !endif
+!endif
 
 0x00000000|0x0000e000
 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageVariableBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
 #NV_VARIABLE_STORE
 DATA = {
   ## This is the EFI_FIRMWARE_VOLUME_HEADER
   # ZeroVector []
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -106,30 +126,58 @@ DATA = {
   # WriteQueueSize: UINT64
   0xE0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 }
 
 0x00010000|0x00010000
 #NV_FTW_SPARE
 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
 
+!ifdef $(SPLIT_VARSTORE)
+!ifdef $(FD_SIZE_1MB)
+[FD.OVMF]
+BaseAddress   = 0xFFF20000
+Size          = 0x000E0000
+ErasePolarity = 1
+BlockSize     = 0x1000
+NumBlocks     = 0xE0
+
+0x00000000|0x000CC000
+FV = FVMAIN_COMPACT
+0x000CC000|0x14000
+FV = SECFV
+!else
+[FD.OVMF]
+BaseAddress   = 0xFFE20000
+Size          = 0x001E0000
+ErasePolarity = 1
+BlockSize     = 0x1000
+NumBlocks     = 0x1E0
+
+0x00000000|0x001AC000
+FV = FVMAIN_COMPACT
+0x001AC000|0x34000
+FV = SECFV
+!endif
+!else
 !ifdef $(FD_SIZE_1MB)
 0x00020000|0x000CC000
 FV = FVMAIN_COMPACT
 
 0x000EC000|0x14000
 FV = SECFV
 
 !else
 0x00020000|0x001AC000
 FV = FVMAIN_COMPACT
 
 0x001CC000|0x34000
 FV = SECFV
 !endif
+!endif
 
 ################################################################################
 
 [FD.MEMFD]
 BaseAddress   = 0x800000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfMemFvBase
 Size          = 0x800000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfMemFvSize
 ErasePolarity = 1
 BlockSize     = 0x10000
diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf
index 751b94b..81cfff6 100644
--- a/OvmfPkg/OvmfPkgX64.fdf
+++ b/OvmfPkg/OvmfPkgX64.fdf
@@ -23,31 +23,51 @@
 #
 [Defines]
 !if $(TARGET) == RELEASE
 !ifndef $(FD_SIZE_2MB)
 DEFINE FD_SIZE_1MB=
 !endif
 !endif
 
+!ifdef $(SPLIT_VARSTORE)
+!ifdef $(FD_SIZE_1MB)
+[FD.NvVarStore]
+BaseAddress   = 0xFFF00000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
+SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize = 0x00100000
+Size          = 0x20000
+ErasePolarity = 1
+BlockSize     = 0x1000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareBlockSize
+NumBlocks     = 0x20
+!else
+[FD.NvVarStore]
+BaseAddress   = 0xFFE00000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
+SET gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize = 0x00200000
+Size          = 0x20000
+ErasePolarity = 1
+BlockSize     = 0x1000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareBlockSize
+NumBlocks     = 0x20
+!endif
+!else
 !ifdef $(FD_SIZE_1MB)
 [FD.OVMF]
 BaseAddress   = 0xFFF00000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
 Size          = 0x00100000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize
 ErasePolarity = 1
 BlockSize     = 0x1000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareBlockSize
 NumBlocks     = 0x100
 !else
 [FD.OVMF]
 BaseAddress   = 0xFFE00000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
 Size          = 0x00200000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize
 ErasePolarity = 1
 BlockSize     = 0x1000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareBlockSize
 NumBlocks     = 0x200
 !endif
+!endif
 
 0x00000000|0x0000e000
 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageVariableBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
 #NV_VARIABLE_STORE
 DATA = {
   ## This is the EFI_FIRMWARE_VOLUME_HEADER
   # ZeroVector []
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -106,30 +126,58 @@ DATA = {
   # WriteQueueSize: UINT64
   0xE0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 }
 
 0x00010000|0x00010000
 #NV_FTW_SPARE
 gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
 
+!ifdef $(SPLIT_VARSTORE)
+!ifdef $(FD_SIZE_1MB)
+[FD.OVMF]
+BaseAddress   = 0xFFF20000
+Size          = 0x000E0000
+ErasePolarity = 1
+BlockSize     = 0x1000
+NumBlocks     = 0xE0
+
+0x00000000|0x000CC000
+FV = FVMAIN_COMPACT
+0x000CC000|0x14000
+FV = SECFV
+!else
+[FD.OVMF]
+BaseAddress   = 0xFFE20000
+Size          = 0x001E0000
+ErasePolarity = 1
+BlockSize     = 0x1000
+NumBlocks     = 0x1E0
+
+0x00000000|0x001AC000
+FV = FVMAIN_COMPACT
+0x001AC000|0x34000
+FV = SECFV
+!endif
+!else
 !ifdef $(FD_SIZE_1MB)
 0x00020000|0x000CC000
 FV = FVMAIN_COMPACT
 
 0x000EC000|0x14000
 FV = SECFV
 
 !else
 0x00020000|0x001AC000
 FV = FVMAIN_COMPACT
 
 0x001CC000|0x34000
 FV = SECFV
 !endif
+!endif
 
 ################################################################################
 
 [FD.MEMFD]
 BaseAddress   = 0x800000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfMemFvBase
 Size          = 0x800000|gUefiOvmfPkgTokenSpaceGuid.PcdOvmfMemFvSize
 ErasePolarity = 1
 BlockSize     = 0x10000
diff --git a/OvmfPkg/README b/OvmfPkg/README
index f2c2fc7..6f7dc38 100644
--- a/OvmfPkg/README
+++ b/OvmfPkg/README
@@ -48,16 +48,19 @@ Update Conf/target.txt TARGET_ARCH based on the .dsc file:
 Following the edk2 build process, you will find the OVMF binaries
 under the $WORKSPACE/Build/*/*/FV directory.  The actual path will
 depend on how your build is configured.  You can expect to find
 these binary outputs:
 * OVMF.FD
   - Please note!  This filename has changed.  Older releases used OVMF.Fv.
 * OvmfVideo.rom
   - This file is not built separately any longer, starting with svn r13520.
+* NVVARSTORE.fd
+  - This file is only produced when -D SPLIT_VARSTORE is passed to the build
+    utility. (See more under "OVMF Flash Layout".)
 
 More information on building OVMF can be found at:
 
 http://sourceforge.net/apps/mediawiki/tianocore/index.php?title=How_to_build_OVMF
 
 === RUNNING OVMF on QEMU ===
 
 * QEMU 0.9.1 or later is required.
@@ -211,16 +214,29 @@ OVMF supports building a 1MB or a 2MB flash image. The base address for
 a 1MB image in QEMU physical memory is 0xfff00000. The base address for
 a 2MB image is 0xffe00000.
 
 The code in SECFV locates FVMAIN_COMPACT, and decompresses the
 main firmware (MAINFV) into RAM memory at address 0x800000. The
 remaining OVMF firmware then uses this decompressed firmware
 volume image.
 
+If -D SPLIT_VARSTORE has been passed to the build utility, then the address
+(base + 0x20000) splits the build output in two parts. The address range
+starting at (base + 0x20000) is covered by OVMF.fd (up to 4GB), while the range
+below it (from (base) to (base + 0x20000)) is covered by NVVARSTORE.fd.
+
+This is useful for centrally managing the binary part (OVMF.fd) on a host
+system, while allowing virtual machines to keep their private variable stores.
+Qemu-1.8 is expected to support this use case with the following options
+(specified in this order):
+
+      -drive file=/central/OVMF.fd,if=pflash,format=raw,readonly \
+      -drive file=/images/NVVARSTORE.fd.vm1,if=pflash,format=raw
+
 === UNIXGCC Debug ===
 
 If you build with the UNIXGCC toolchain, then debugging will be disabled
 due to larger image sizes being produced by the UNIXGCC toolchain. The
 first choice recommendation is to use GCC44 or newer instead.
 
 If you must use UNIXGCC, then you can override the build options for
 particular libraries and modules in the .dsc to re-enable debugging
