Commit Graph

1289 Commits

Author SHA1 Message Date
Marc-André Lureau 5487d002fa OvmfPkg: simplify SecurityStubDxe.inf inclusion
SecurityStubDxe.inf should be included unconditionally.

Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2018-03-09 18:09:10 +01:00
Laszlo Ersek 5e2e5647b9 OvmfPkg/AmdSevDxe: decrypt the pages of the initial SMRAM save state map
Based on the following patch from Brijesh Singh <brijesh.singh@amd.com>:

  [PATCH v2 1/2] OvmfPkg/AmdSevDxe: Clear the C-bit from SMM Saved State
  http://mid.mail-archive.com/20180228161415.28723-2-brijesh.singh@amd.com
  https://lists.01.org/pipermail/edk2-devel/2018-February/022016.html

Original commit message from Brijesh:

> When OVMF is built with SMM, SMMSaved State area (SMM_DEFAULT_SMBASE +
> SMRAM_SAVE_STATE_MAP_OFFSET) contains data which need to be accessed by
> both guest and hypervisor. Since the data need to be accessed by both
> hence we must map the SMMSaved State area as unencrypted (i.e C-bit
> cleared).
>
> This patch clears the SavedStateArea address before SMBASE relocation.
> Currently, we do not clear the SavedStateArea address after SMBASE is
> relocated due to the following reasons:
>
> 1) Guest BIOS never access the relocated SavedStateArea.
>
> 2) The C-bit works on page-aligned address, but the SavedStateArea
> address is not a page-aligned. Theoretically, we could roundup the
> address and clear the C-bit of aligned address but looking carefully we
> found that some portion of the page contains code -- which will causes a
> bigger issue for the SEV guest. When SEV is enabled, all the code must
> be encrypted otherwise hardware will cause trap.

Changes by Laszlo:

- separate AmdSevDxe bits from SmmCpuFeaturesLib bits;

- spell out PcdLib dependency with #include and in LibraryClasses;

- replace (SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET) calculation
  with call to new MemEncryptSevLocateInitialSmramSaveStateMapPages()
  function;

- consequently, pass page-aligned BaseAddress to
  MemEncryptSevClearPageEncMask();

- zero the pages before clearing the C-bit;

- pass Flush=TRUE to MemEncryptSevClearPageEncMask();

- harden the treatment of MemEncryptSevClearPageEncMask() failure.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2018-03-06 13:30:38 +01:00
Laszlo Ersek 5ef3b66fec OvmfPkg/SmmCpuFeaturesLib: SEV: encrypt+free pages of init. save state map
Based on the following patch from Brijesh Singh <brijesh.singh@amd.com>:

  [PATCH v2 1/2] OvmfPkg/AmdSevDxe: Clear the C-bit from SMM Saved State
  http://mid.mail-archive.com/20180228161415.28723-2-brijesh.singh@amd.com
  https://lists.01.org/pipermail/edk2-devel/2018-February/022016.html

Once PiSmmCpuDxeSmm relocates SMBASE for all VCPUs, the pages of the
initial SMRAM save state map can be re-encrypted (including zeroing them
out after setting the C-bit on them), and they can be released to DXE for
general use (undoing the allocation that we did in PlatformPei's
AmdSevInitialize() function).

The decryption of the same pages (which will occur chronologically
earlier) is implemented in the next patch; hence the "re-encryption" part
of this patch is currently a no-op. The series is structured like this in
order to be bisection-friendly. If the decryption patch preceded this
patch, then an info leak would be created while standing between the
patches.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2018-03-06 13:30:35 +01:00
Laszlo Ersek 86defc2c25 OvmfPkg/PlatformPei: SEV: allocate pages of initial SMRAM save state map
In the next two patches, we'll temporarily decrypt the pages containing
the initial SMRAM save state map, for SMBASE relocation. (Unlike the
separate, relocated SMRAM save state map of each VCPU, the original,
shared map behaves similarly to a "common buffer" between guest and host.)
The decryption will occur near the beginning of the DXE phase, in
AmdSevDxe, and the re-encryption will occur in PiSmmCpuDxeSmm, via OVMF's
SmmCpuFeaturesLib instance.

There is a non-trivial time gap between these two points, and the DXE
phase might use the pages overlapping the initial SMRAM save state map for
arbitrary purposes meanwhile. In order to prevent any information leak
towards the hypervisor, make sure the DXE phase puts nothing in those
pages until re-encryption is done.

Creating a memalloc HOB for the area in question is safe:

- the temporary SEC/PEI RAM (stack and heap) is based at
  PcdOvmfSecPeiTempRamBase, which is above 8MB,

- the permanent PEI RAM (installed in PlatformPei's PublishPeiMemory()
  function) never starts below PcdOvmfDxeMemFvBase, which is also above
  8MB.

The allocated pages can be released to the DXE phase after SMBASE
relocation and re-encryption are complete.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2018-03-06 13:30:32 +01:00
Laszlo Ersek 61a044c6c1 OvmfPkg/MemEncryptSevLib: find pages of initial SMRAM save state map
In the next three patches, we're going to modify three modules under
OvmfPkg. When OVMF is built with -D SMM_REQUIRE and runs in an SEV guest,
each affected module will have to know the page range that covers the
initial (pre-SMBASE relocation) SMRAM save state map. Add a helper
function to MemEncryptSevLib that calculates the "base address" and
"number of pages" constants for this page range.

(In a RELEASE build -- i.e., with assertions disabled and optimization
enabled --, the helper function can be compiled to store two constants
determined at compile time.)

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2018-03-06 13:30:30 +01:00
Laszlo Ersek cd66bd7316 OvmfPkg/AmdSevDxe: refresh #includes and LibraryClasses
List those and only those libraries that are used.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2018-03-06 13:30:28 +01:00
Laszlo Ersek c6073a0ead OvmfPkg/AmdSevDxe: sort #includes, and entries in INF file sections
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2018-03-06 13:30:26 +01:00
Laszlo Ersek c16d4e35d1 OvmfPkg/AmdSevDxe: rewrap to 79 characters width
There are many overlong lines; it's hard to work with the module like
this. Rewrap all files to 79 columns.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2018-03-06 13:30:24 +01:00
Laszlo Ersek e1e0428615 OvmfPkg/SmmCpuFeaturesLib: remove unneeded #includes and LibraryClasses
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2018-03-06 13:30:22 +01:00
Laszlo Ersek 4a9b250bca OvmfPkg/SmmCpuFeaturesLib: sort #includes, and entries in INF file sections
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2018-03-06 13:30:20 +01:00
Laszlo Ersek ea992760ff OvmfPkg/SmmCpuFeaturesLib: upper-case the "static" keyword
In edk2, the "static" keyword is spelled "STATIC". Also let "STATIC" stand
alone on a line in function definitions.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2018-03-06 13:30:18 +01:00
Laszlo Ersek b1bfdd6597 OvmfPkg/SmmCpuFeaturesLib: rewrap to 79 columns
There are many overlong lines; it's hard to work with the library like
this. Rewrap all files to 79 columns.

(

The rewrapping of the "mSmmCpuRegisterRanges" and "mSmmCpuWidthOffset"
arrays was verified by hexdumping the arrays in
SmmCpuFeaturesLibConstructor(), both before and after the patch, and
comparing the dumps.

Contents of "mSmmCpuRegisterRanges", IA32 build:

> mSmmCpuRegisterRanges: {
> mSmmCpuRegisterRanges: 000000 04 00 00 00 0A 00 00 00 07 00 00 00 14 00 00 00
> mSmmCpuRegisterRanges: 000010 2E 00 00 00 1B 00 00 00 33 00 00 00 36 00 00 00
> mSmmCpuRegisterRanges: 000020 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> mSmmCpuRegisterRanges: }

Contents of "mSmmCpuRegisterRanges", X64 build:

> mSmmCpuRegisterRanges: {
> mSmmCpuRegisterRanges: 000000 04 00 00 00 0A 00 00 00 07 00 00 00 00 00 00 00
> mSmmCpuRegisterRanges: 000010 14 00 00 00 2E 00 00 00 1B 00 00 00 00 00 00 00
> mSmmCpuRegisterRanges: 000020 33 00 00 00 36 00 00 00 04 00 00 00 00 00 00 00
> mSmmCpuRegisterRanges: 000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> mSmmCpuRegisterRanges: }

Contents of "mSmmCpuWidthOffset", both IA32 and X64 builds:

> mSmmCpuWidthOffset: {
> mSmmCpuWidthOffset: 000000 00 00 00 00 00 00 00 00 00 00 00 08 00 00 68 02
> mSmmCpuWidthOffset: 000010 6C 02 00 00 00 08 00 00 88 02 8C 02 00 00 00 08
> mSmmCpuWidthOffset: 000020 00 00 78 02 7C 02 00 00 00 00 00 00 64 02 68 02
> mSmmCpuWidthOffset: 000030 00 00 00 00 00 00 84 02 88 02 00 00 00 00 00 00
> mSmmCpuWidthOffset: 000040 74 02 78 02 00 00 00 00 00 00 00 00 04 00 00 00
> mSmmCpuWidthOffset: 000050 04 04 A8 03 00 02 00 00 00 00 04 04 AC 03 10 02
> mSmmCpuWidthOffset: 000060 00 00 00 00 04 04 B0 03 20 02 00 00 00 00 04 04
> mSmmCpuWidthOffset: 000070 B4 03 30 02 00 00 00 00 04 04 B8 03 40 02 00 00
> mSmmCpuWidthOffset: 000080 00 00 04 04 BC 03 50 02 00 00 00 00 00 04 00 00
> mSmmCpuWidthOffset: 000090 70 02 00 00 00 00 04 04 C4 03 90 02 00 00 00 00
> mSmmCpuWidthOffset: 0000A0 04 08 C8 03 60 03 64 03 00 00 04 08 CC 03 68 03
> mSmmCpuWidthOffset: 0000B0 6C 03 00 00 00 08 00 00 B8 03 BC 03 01 00 00 08
> mSmmCpuWidthOffset: 0000C0 00 00 B0 03 B4 03 01 00 00 08 00 00 A8 03 AC 03
> mSmmCpuWidthOffset: 0000D0 01 00 00 08 00 00 A0 03 A4 03 01 00 00 08 00 00
> mSmmCpuWidthOffset: 0000E0 98 03 9C 03 01 00 00 08 00 00 90 03 94 03 01 00
> mSmmCpuWidthOffset: 0000F0 00 08 00 00 88 03 8C 03 01 00 00 08 00 00 80 03
> mSmmCpuWidthOffset: 000100 84 03 01 00 04 08 D0 03 F8 03 FC 03 01 00 04 08
> mSmmCpuWidthOffset: 000110 DC 03 E0 03 E4 03 01 00 04 08 D4 03 F0 03 F4 03
> mSmmCpuWidthOffset: 000120 01 00 04 08 D8 03 E8 03 EC 03 01 00 04 08 E0 03
> mSmmCpuWidthOffset: 000130 D8 03 DC 03 01 00 04 08 E4 03 D0 03 D4 03 01 00
> mSmmCpuWidthOffset: 000140 04 08 E8 03 C8 03 CC 03 01 00 04 08 EC 03 C0 03
> mSmmCpuWidthOffset: 000150 C4 03 01 00 04 08 F0 03 78 03 7C 03 01 00 04 08
> mSmmCpuWidthOffset: 000160 F4 03 70 03 74 03 01 00 04 08 FC 03 58 03 5C 03
> mSmmCpuWidthOffset: 000170 00 00 04 08 F8 03 50 03 54 03 00 00 00 04 00 00
> mSmmCpuWidthOffset: 000180 48 03 4C 03 00 00
> mSmmCpuWidthOffset: }

)

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2018-03-06 13:30:14 +01:00
Laszlo Ersek 6d576e7ac4 OvmfPkg/PlatformPei: sort #includes in "AmdSev.c"
No functional changes.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2018-03-06 13:30:13 +01:00
Laszlo Ersek bd13ecf355 OvmfPkg/MemEncryptSevLib: sort #includes, and entries in INF file sections
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2018-03-06 13:30:10 +01:00
Laszlo Ersek 68e60a388d OvmfPkg/MemEncryptSevLib: clean up InternalMemEncryptSevSetMemoryEncrypted() decl
The declaration and the definition(s) of the function should have
identical leading comments and/or identical parameter lists. Document the
"Cr3BaseAddress" parameter, and correct several parameter references.
Replace a "clear" reference to the C-bit with a "set" reference.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2018-03-06 13:30:09 +01:00
Laszlo Ersek 1532e5d5ed OvmfPkg/MemEncryptSevLib: clean up InternalMemEncryptSevSetMemoryDecrypted() decl
The declaration and the definition(s) of the function should have
identical leading comments and/or identical parameter lists. Document the
"Cr3BaseAddress" parameter, and correct several parameter references.
Replace a "set" reference to the C-bit with a "clear" reference.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2018-03-06 13:30:07 +01:00
Laszlo Ersek cde8c56809 OvmfPkg/MemEncryptSevLib: clean up SetMemoryEncDec() comment block
Document the "Cr3BaseAddress" parameter, and correct several parameter
references.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2018-03-06 13:30:05 +01:00
Laszlo Ersek 154dcd6c58 OvmfPkg/MemEncryptSevLib: clean up MemEncryptSevSetPageEncMask() decl
The declaration and the definition(s) of the function should have
identical leading comments and/or identical parameter lists. Replace any
leftover "clear" references to the C-bit with "set" references. Also
remove any excess space in the comment block, and unindent the trailing
"**/" if necessary. Correct several parameter references.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2018-03-06 13:30:03 +01:00
Laszlo Ersek 5b5028e67b OvmfPkg/MemEncryptSevLib: clean up MemEncryptSevClearPageEncMask() decl
The declaration and the definition(s) of the function should have
identical leading comments and/or identical parameter lists. Also remove
any excess space in the comment block, and unindent the trailing "**/" if
necessary. Correct several parameter references.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2018-03-06 13:30:01 +01:00
Laszlo Ersek d4dd22c7bc OvmfPkg/MemEncryptSevLib: clean up MemEncryptSevIsEnabled() decl
The declaration and the definition(s) of the function should have
identical leading comments and/or identical parameter lists. Also remove
any excess space in the comment block, and unindent the trailing "**/" if
necessary.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2018-03-06 13:29:58 +01:00
Laszlo Ersek 4bd6bf317e OvmfPkg/MemEncryptSevLib: rewrap to 79 characters width
There are many overlong lines; it's hard to work with the library like
this. Rewrap all files to 79 columns.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2018-03-06 13:29:37 +01:00
Laszlo Ersek f3f80a57e1 OvmfPkg: drop stale SafeBlockIoLib and SafeOpenProtocolLib resolutions
These are listed under "ShellPkg/Application/Shell/Shell.inf", but they
have been commented out ever since commit 345a0c8fce ("OvmfPkg: Add
support for UEFI shell", 2011-06-26). No such lib classes exist in edk2.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Jaben Carsey <jaben.carsey@intel.com>
2018-02-13 13:29:19 +01:00
Michael D Kinney 7fc21c29e8 OvmfPkg: Add SafeIntLib and BmpSupportLib to DSC files
https://bugzilla.tianocore.org/show_bug.cgi?id=800

Based on content from the following branch/commits:
https://github.com/Microsoft/MS_UEFI/tree/share/MsCapsuleSupport
33bab4031a
ca516b1a61
2b9f111f2e

The BootGraphicsResourceTableDxe module uses the BmpSupportLib
and SafeIntLib to convert a GOP BLT buffer to a BMP graphics image.
Add library mappings for these new library classes.

Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Bret Barkelew <Bret.Barkelew@microsoft.com>
2018-02-11 16:06:07 -08:00
Laszlo Ersek c0d221a348 OvmfPkg/PlatformPei: sync AmdSevInitialize() definition with declaration
"Platform.h" declares the AmdSevInitialize() function without EFIAPI, but
the definition in "AmdSev.c" includes EFIAPI.

GCC toolchains without LTO do not catch this error because "AmdSev.c" does
not include "Platform.h"; i.e. the declaration used by callers such as
"Platform.c" is not actually matched against the function definition at
build time.

With LTO enabled, the mismatch is found -- however, as a warning only, due
to commit f8d0b96629 ("BaseTools GCC5: disable warnings-as-errors for
now", 2016-08-03).

Include the header in the C file (which turns the issue into a hard build
error on all GCC toolchains), plus sync the declaration from the header
file to the C file.

There's been no functional breakage because AmdSevInitialize() takes no
parameters.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Fixes: 13b5d743c8
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Jaben Carsey <jaben.carsey@intel.com>
Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
2018-02-08 18:23:32 +01:00
Liming Gao 4a64cbda86 OvmfPkg: Don't add -mno-mmx -mno-sse option for XCODE5 tool chain
Ovmf appended option -mno-mmx -mno-sse, but these two options were enabled
in Openssl. The compiler option becomes -mmmx ?msse -mno-mmx -mno-sse. It
trig mac clang compiler hang when compile one source file in openssl.
This issue is found when SECURE_BOOT_ENABLE is TRUE. This may be the compiler
issue. To work around it, don't add these two options for XCODE5 tool chain.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Liming Gao <liming.gao@intel.com>
Cc: Andrew Fish <afish@apple.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2018-01-16 23:43:15 +08:00
Brijesh Singh b721aa749b OvmfPkg/BaseMemEncryptSevLib: Enable protection for newly added page table
Commit 2ac1730bf2 (MdeModulePkg/DxeIpl: Mark page table as read-only)
sets the memory pages used for page table as read-only after paging is
setup and sets CR0.WP to protect CPU modifying the read-only pages.
The commit causes #PF when MemEncryptSevClearPageEncMask() or
MemEncryptSevSetPageEncMask() tries to change the page-table attributes.

This patch takes the similar approach as Commit 147fd35c3e
(UefiCpuPkg/CpuDxe: Enable protection for newly added page table).
When page table protection is enabled, we disable it temporarily before
changing the page table attributes.

This patch makes use of the same approach as Commit 2ac1730bf2
(MdeModulePkg/DxeIpl: Mark page table as read-only)) for allocating
page table memory from reserved memory pool, which helps to reduce a
potential "split" operation.

The patch duplicates code from commit 147fd35c3e. The code duplication
will be removed after we implement page table manipulation library. See
bugzilla https://bugzilla.tianocore.org/show_bug.cgi?id=847.

Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
2018-01-15 21:18:50 +01:00
Ruiyu Ni 984ba6a467 OvmfPkg: Add tftp dynamic command
The TFTP command was converted from a NULL class library instance
to a dynamic shell command in commit 0961002352.
This patch complements commit f9bc2f8763, which only removed the
old library, but didn't add the new dynamic command。

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: Julien Grall <julien.grall@linaro.org>
2017-11-29 10:56:13 +08:00
Ruiyu Ni 46c6b956af OvmfPkg/Sec: Fix 64bit SEC build failure
Original code breaks a single assembly code to multiple lines.
But, when VS CL.exe preprocesses the FixedPcdGet32() macro
invocation to the replacement text, it loses '\', and causes
NASM to fail.

Changing the multiple lines to one line to resolve the build failure.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2017-11-29 10:42:25 +08:00
Laszlo Ersek dc32e820f0 OvmfPkg/QemuBootOrderLib: let an OFW devpath match multiple UEFI boot opts
This means that SetBootOrderFromQemu() will preserve all UEFI boot options
matched by any given OFW devpath, such as PXEv4, HTTPv4, PXEv6 and HTTPv6
boot options for the same NIC. Currently we stop the matching / appending
for the OFW devpath coming from the outer loop whenever we find the first
UEFI boot option match in the inner loop.

(The previous patch was about multiple OFW devpaths matching a single UEFI
boot option (which should never happen). This patch is about a single OFW
devpath matching multiple UEFI boot options. With the "break" statement
removed here, the small optimization from the last patch becomes a bit
more relevant, because now the inner loop always counts up to
ActiveCount.)

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
2017-11-28 21:37:11 +01:00
Laszlo Ersek a0e761b153 OvmfPkg/QemuBootOrderLib: skip already matched / appended UEFI boot opts
The SetBootOrderFromQemu() function implements a nested loop where

- the outer loop iterates over all OpenFirmware (OFW) device paths in the
  QEMU boot order, and translates each to a UEFI device path prefix;

- the inner loop matches the current (translated) prefix against all
  active UEFI boot options in turn;

- if the UEFI boot option is matched by the translated prefix, the UEFI
  boot option is appended to the "new" UEFI boot order, and marked as
  "has been appended".

This patch adds a micro-optimization where already matched / appended UEFI
boot options are skipped in the inner loop. This is not a functional
change. A functional change would be if, as a consequence of the patch,
some UEFI boot options would no longer be *doubly* matched.

For a UEFI boot option to be matched by two translated prefixes, one of
those prefixes would have to be a (proper, or equal) prefix of the other
prefix. The PCI and MMIO OFW translation routines output such only in the
following cases:

- When the original OFW device paths are prefixes of each other. This is
  not possible from the QEMU side. (Only leaf devices are bootable.)

- When the translation rules in the routines are incomplete, and don't
  look at the OFW device paths for sufficient length (i.e., at nodes where
  they would already differ, and the difference would show up in the
  translation output).

  This would be a shortcoming of the translation routines and should be
  fixed in TranslatePciOfwNodes() and TranslateMmioOfwNodes(), whenever
  identified.

Even in the second case, this patch would replace the double appending of
a single UEFI boot option (matched by two different OFW device paths) with
a correct, or cross-, matching of two different UEFI boot options. Again,
this is not expected, but arguably it would be more correct than duplicate
boot option appending, should it occur due to any (unexpected, unknown)
lack of detail in the translation routines.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
2017-11-28 21:36:53 +01:00
Ruiyu Ni f9bc2f8763 OvmfPkg: Fix build failure due to Tftp library removal
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
2017-11-28 15:23:46 +08:00
Paolo Bonzini c09d957130 OvmfPkg: save on I/O port accesses when the debug port is not in use
When SEV is enabled, every debug message printed by OVMF to the
QEMU debug port traps from the guest to QEMU character by character
because "REP OUTSB" cannot be used by IoWriteFifo8.  Furthermore,
when OVMF is built with the DEBUG_VERBOSE bit (value 0x00400000)
enabled in "gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel", then the
OvmfPkg/IoMmuDxe driver, and the OvmfPkg/Library/BaseMemEncryptSevLib
library instance that is built into it, produce a huge amount of
log messages.  Therefore, in SEV guests, the boot time impact is huge
(about 45 seconds _additional_ time spent writing to the debug port).

While these messages are very useful for analyzing guest behavior,
most of the time the user won't be capturing the OVMF debug log.
In fact libvirt does not provide a method for configuring log capture;
users that wish to do this (or are instructed to do this) have to resort
to <qemu:arg>.

The debug console device provides a handy detection mechanism; when read,
it returns 0xE9 (which is very much unlike the 0xFF that is returned by
an unused port).  Use it to skip the possibly expensive OUT instructions
when the debug I/O port isn't plugged anywhere.

For SEC, the debug port has to be read before each full message.
However:

- if the debug port is available, then reading one byte before writing
a full message isn't tragic, especially because SEC doesn't print many
messages

- if the debug port is not available, then reading one byte instead of
writing a full message is still a win.

Contributed-under: TianoCore Contribution Agreement 1.0
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen (Intel address) <jordan.l.justen@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2017-11-17 18:35:12 +01:00
Paolo Bonzini c9eb56e5fd OvmfPkg: create a separate PlatformDebugLibIoPort instance for SEC
The next patch will want to add a global variable to
PlatformDebugLibIoPort, but this is not suitable for the SEC
phase, because SEC runs from read-only flash.  The solution is
to have two library instances, one for SEC and another
for all other firmware phases.  This patch adds the "plumbing"
for the SEC library instance, separating the INF files and
moving the constructor to a separate C source file.

Contributed-under: TianoCore Contribution Agreement 1.1
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen (Intel address) <jordan.l.justen@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2017-11-17 18:35:08 +01:00
Paolo Bonzini 6dead8d5af OvmfPkg: make PlatformDebugLibIoPort a proper BASE library
Remove Uefi.h, which includes UefiSpec.h, and change the
return value to match the RETURN_STATUS type.

Contributed-under: TianoCore Contribution Agreement 1.1
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen (Intel address) <jordan.l.justen@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2017-11-17 18:34:56 +01:00
Laszlo Ersek d41fd8e839 OvmfPkg: restore temporary SEC/PEI RAM size to 64KB
(1) In the PEI phase, the PCD database is maintained in a GUID HOB. In
    OVMF, we load the PCD PEIM before any other PEIMs (using APRIORI PEI),
    so that all other PEIMs can use dynamic PCDs. Consequently,

    - the PCD GUID HOB is initially allocated from the temporary SEC/PEI
      heap,

    - whenever we introduce a dynamic PCD to a PEIM built into OVMF such
      that the PCD is new to OVMF's whole PEI phase, the PCD GUID HOB (and
      its temporary heap footprint) grow.

    I've noticed that, if we add just one more dynamic PCD to the PEI
    phase, then in the X64 build,

    - we get very close to the half of the temporary heap (i.e., 8192
      bytes),

    - obscure PEI phase hangs or DXE core initialization failures
      (ASSERTs) occur. The symptoms vary between the FD_SIZE_2MB and
      FD_SIZE_4MB builds of X64 OVMF.

(2) I've found that commit

      2bbd7e2fbd ("UefiCpuPkg/MtrrLib: Update algorithm to calculate
                    optimal settings", 2017-09-27)

    introduced a large (16KB) stack allocation:

> The patch changes existing MtrrSetMemoryAttributeInMtrrSettings() and
> MtrrSetMemoryAttribute() to use the 4-page stack buffer for calculation.
> ...
> +#define SCRATCH_BUFFER_SIZE           (4 * SIZE_4KB)
> ...
> @@ -2207,17 +2462,66 @@ MtrrSetMemoryAttributeInMtrrSettings (
> ...
> +  UINT8                      Scratch[SCRATCH_BUFFER_SIZE];

(3) OVMF's temp SEC/PEI RAM size has been 32KB ever since commit

      7cb6b0e068 ("OvmfPkg: Move SEC/PEI Temporary RAM from 0x70000 to
                    0x810000", 2014-01-21)

    Of that, the upper 16KB half is stack (growing down), and the lower
    16KB half is heap.

    Thus, OvmfPkg/PlatformPei's calls to "UefiCpuPkg/Library/MtrrLib", in
    QemuInitializeRam(), cause the Scratch array to overflow the entire
    stack (heading towards lower addresses), and corrupt the heap below
    the stack. It turns out that the total stack demand is about 24KB, so
    the overflow is able to corrupt the upper 8KB of the heap. If that
    part of the heap is actually used (for example because we grow the PCD
    GUID HOB sufficiently), mayhem ensues.

(4) Right after commit 7cb6b0e068 (see above), there would be no room
    left above the 32KB temp SEC/PEI RAM. However, given more recent
    commits

      45d8708151 ("OvmfPkg/PlatformPei: rebase and resize the permanent
                    PEI memory for S3", 2016-07-13)

      6b04cca4d6 ("OvmfPkg: remove PcdS3AcpiReservedMemoryBase,
                    PcdS3AcpiReservedMemorySize", 2016-07-12)

    we can now restore the temp SEC/PEI RAM size to the original
    (pre-7cb6b0e06809) 64KB. This will allow for a 32KB temp SEC/PEI
    stack, which accommodates the ~24KB demand mentioned in (3).

    (Prior patches in this series will let us monitor the stack usage in
    the future.)

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=747
Ref: http://mid.mail-archive.com/a49cc089-12ae-a887-a4d6-4dc509233a74@redhat.com
Ref: http://mid.mail-archive.com/03e369bb-77c4-0134-258f-bdae62cbc8c5@redhat.com
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2017-11-17 18:12:18 +01:00
Laszlo Ersek 2278b8a82e OvmfPkg/Sec/X64: seed the temporary RAM with PcdInitValueInTempStack
This allows the PEI core to report the maximum temporary SEC/PEI stack
usage on the DEBUG_INFO level, in the PeiCheckAndSwitchStack() function
[MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c]:

* Normal boot:

> Temp Stack : BaseAddress=0x814000 Length=0x4000
> Temp Heap  : BaseAddress=0x810000 Length=0x4000
> Total temporary memory:    32768 bytes.
>   temporary memory stack ever used:       5080 bytes. <----
>   temporary memory heap used for HobList: 8080 bytes.
>   temporary memory heap occupied by memory pages: 0 bytes.

* S3 resume (no SMM / PEI decompression)

> Temp Stack : BaseAddress=0x814000 Length=0x4000
> Temp Heap  : BaseAddress=0x810000 Length=0x4000
> Total temporary memory:    32768 bytes.
>   temporary memory stack ever used:       5048 bytes. <----
>   temporary memory heap used for HobList: 7112 bytes.
>   temporary memory heap occupied by memory pages: 0 bytes.

I unit-tested this change by transitorily adding an infinite loop right
after the "rep stosq", and dumping the guest's temp SEC/PEI RAM (32KB
currently) while the guest was stuck in the loop. The dump includes one
dword from before and after the temp SEC/PEI RAM:

> $ virsh qemu-monitor-command GUEST_NAME --hmp 'xp /8194wx 0x80FFFC'
>
> 000000000080fffc: 0x00000000 0x5aa55aa5 0x5aa55aa5 0x5aa55aa5
> 000000000081000c: 0x5aa55aa5 0x5aa55aa5 0x5aa55aa5 0x5aa55aa5
> ...
> 0000000000817fec: 0x5aa55aa5 0x5aa55aa5 0x5aa55aa5 0x5aa55aa5
> 0000000000817ffc: 0x5aa55aa5 0x00000000

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=747
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2017-11-17 18:12:15 +01:00
Laszlo Ersek 9d9350a579 OvmfPkg/Sec/Ia32: seed the temporary RAM with PcdInitValueInTempStack
This allows the PEI core to report the maximum temporary SEC/PEI stack
usage on the DEBUG_INFO level, in the PeiCheckAndSwitchStack() function
[MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c]:

* Normal boot:

> Temp Stack : BaseAddress=0x814000 Length=0x4000
> Temp Heap  : BaseAddress=0x810000 Length=0x4000
> Total temporary memory:    32768 bytes.
>   temporary memory stack ever used:       3664 bytes. <----
>   temporary memory heap used for HobList: 5904 bytes.
>   temporary memory heap occupied by memory pages: 0 bytes.

* S3 resume (with PEI decompression / SMM):

> Temp Stack : BaseAddress=0x814000 Length=0x4000
> Temp Heap  : BaseAddress=0x810000 Length=0x4000
> Total temporary memory:    32768 bytes.
>   temporary memory stack ever used:       3428 bytes. <----
>   temporary memory heap used for HobList: 4816 bytes.
>   temporary memory heap occupied by memory pages: 0 bytes.

I unit-tested this change by transitorily adding an infinite loop right
after the "rep stosd", and dumping the guest's temp SEC/PEI RAM (32KB
currently) while the guest was stuck in the loop. The dump includes one
dword from before and after the temp SEC/PEI RAM:

> $ virsh qemu-monitor-command GUEST_NAME --hmp 'xp /8194wx 0x80FFFC'
>
> 000000000080fffc: 0x00000000 0x5aa55aa5 0x5aa55aa5 0x5aa55aa5
> 000000000081000c: 0x5aa55aa5 0x5aa55aa5 0x5aa55aa5 0x5aa55aa5
> ...
> 0000000000817fec: 0x5aa55aa5 0x5aa55aa5 0x5aa55aa5 0x5aa55aa5
> 0000000000817ffc: 0x5aa55aa5 0x00000000

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=747
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2017-11-17 18:12:12 +01:00
Ard Biesheuvel 12c6484058 OvmfPkg/XenHypercallLib: enable virt extensions for ARM
XenHypercallLib uses the 'hvc' instruction, which is not implemented
on all ARMv7 CPUs, and so we need to explicitly specify a CPU that
has the virtualization extensions.

This override used to be set at the platform level, but this was removed
in commit 0d36a219c7
('ArmPlatformPkg/PL031RealTimeClockLib: drop ArmPlatformSysConfigLib
reference), under the assumption that all users of the 'hvc' instruction
had already been fixed.

So fix this for GNU binutils by adding the 'virt' arch extension
directive, and for RVCT by setting the --cpu command line option to a
CPU that is virt capable.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Acked-by: Laszlo Ersek <lersek@redhat.com>
2017-11-17 09:56:50 +00:00
Laszlo Ersek 1958124a6c OvmfPkg: fix dynamic default for oprom verification policy PCD without SB
I missed the following, both while reviewing and while testing commit
6041ac65ae ("OvmfPkg/PlatformPei: DENY_EXECUTE_ON_SECURITY_VIOLATION
when SEV is active", 2017-10-05):

If "-D SECURE_BOOT_ENABLE" is not passed on the "build" command line, then
OVMF has no dynamic default at all for
"PcdOptionRomImageVerificationPolicy". This means that the PcdSet32S()
call added in the subject commit doesn't even compile:

> OvmfPkg/PlatformPei/AmdSev.c: In function 'AmdSevInitialize':
> OvmfPkg/PlatformPei/AmdSev.c:67:3: error: implicit declaration of
> function '_PCD_SET_MODE_32_S_PcdOptionRomImageVerificationPolicy'
> [-Werror=implicit-function-declaration]
>    PcdStatus = PcdSet32S (PcdOptionRomImageVerificationPolicy, 0x4);
>    ^
> cc1: all warnings being treated as errors

Make the current, SB-only, 0x00 dynamic default unconditional.

This is the simplest approach, and it reflects the intent of original
commit 1fea9ddb4e ("OvmfPkg: execute option ROM images regardless of
Secure Boot", 2016-01-07). Without SECURE_BOOT_ENABLE,
"SecurityPkg/Library/DxeImageVerificationLib" is not used anyway, so the
PCD is never read.

This issue was first caught and reported by Gerd Hoffmann
<kraxel@redhat.com>'s Jenkins CI. Later it was also reported in
<https://bugzilla.tianocore.org/show_bug.cgi?id=737>.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Fixes: 6041ac65ae
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
[lersek@redhat.com: trim commit message as suggested by Jordan]
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
[lersek@redhat.com: add reference to TianoCore BZ#737]
2017-10-19 10:41:09 +02:00
Brijesh Singh 6041ac65ae OvmfPkg/PlatformPei: DENY_EXECUTE_ON_SECURITY_VIOLATION when SEV is active
The following commit:

1fea9ddb4e OvmfPkg: execute option ROM images regardless of Secure Boot

sets the OptionRomImageVerificationPolicy to ALWAYS_EXECUTE the expansion
ROMs attached to the emulated PCI devices. A expansion ROM constitute
another channel through which a cloud provider (i.e hypervisor) can
inject a code in guest boot flow to compromise it.

When SEV is enabled, the bios code has been verified by the guest owner
via the SEV guest launch sequence before its executed. When secure boot,
is enabled, lets make sure that we do not allow guest bios to execute a
code which is not signed by the guest owner.

Fixes: https://bugzilla.tianocore.org/show_bug.cgi?id=728
Cc: Chao Zhang <chao.b.zhang@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2017-10-17 21:28:27 +02:00
Jian J Wang 90f3922b01 OvmfPkg/QemuVideoDxe: Bypass NULL pointer detection during VBE SHIM installing
QemuVideoDxe driver will link VBE SHIM into page 0. If NULL pointer
detection is enabled, this driver will fail to load. NULL pointer detection
bypassing code is added to prevent such problem during boot.

Please note that Windows 7 will try to access VBE SHIM during boot if it's
installed, and then cause boot failure. This can be fixed by setting BIT7
of PcdNullPointerDetectionPropertyMask to disable NULL pointer detection
after EndOfDxe. As far as we know, there's no other OSs has such issue.

Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Michael Kinney <michael.d.kinney@intel.com>
Cc: Ayellet Wolman <ayellet.wolman@intel.com>
Suggested-by: Ayellet Wolman <ayellet.wolman@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Jian J Wang <jian.j.wang@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2017-10-11 16:39:02 +08:00
Laszlo Ersek fe4049471b OvmfPkg/PciHotPlugInitDxe: translate QEMU's resource reservation hints
Parse QEMU_PCI_BRIDGE_CAPABILITY_RESOURCE_RESERVATION from the bridges'
conventional config spaces. Translate the fields as follows:

* BusNumbers:
  * 0 -- no reservation;
  * (-1) -- firmware default, i.e. no reservation;
  * otherwise -- reserve the requested value. (NB, bus number reservation
    is not supposed to work before
    <https://bugzilla.tianocore.org/show_bug.cgi?id=656> is fixed.)

* Io:
  * 0 -- no reservation;
  * (-1) -- keep our current default (512B);
  * otherwise -- round up the requested value and reserve that.

* NonPrefetchable32BitMmio:
  * 0 -- no reservation;
  * (-1) -- keep our current default (2MB);
  * otherwise -- round up the requested value and reserve that.

* Prefetchable32BitMmio:
  * 0 -- no reservation, proceed to Prefetchable64BitMmio;
  * (-1) -- firmware default, i.e. no reservation, proceed to
    Prefetchable64BitMmio;
  * otherwise -- round up the requested value and reserve that. (NB, if
    Prefetchable32BitMmio is reserved in addition to
    NonPrefetchable32BitMmio, then PciBusDxe currently runs into an
    assertion failure. Refer to
    <https://bugzilla.tianocore.org/show_bug.cgi?id=720>.)

* Prefetchable64BitMmio:
  * only reached if Prefetchable32BitMmio was not reserved;
  * 0 -- no reservation;
  * (-1) -- firmware default, i.e. no reservation;
  * otherwise -- round up the requested value and reserve that.

If QEMU_PCI_BRIDGE_CAPABILITY_RESOURCE_RESERVATION is missing, plus any
time the rounding fails, fall back to the current defaults.

Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Marcel Apfelbaum <marcel@redhat.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2017-10-03 16:07:39 +02:00
Laszlo Ersek 4776d5cb3a OvmfPkg/PciHotPlugInitDxe: add helper functions for setting up paddings
Extract the SetIoPadding() and SetMmioPadding() functions, so that we can
set EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR fields using parameter names and
values that are more friendly than the original field names and their
expected values.

Introduce the HighBitSetRoundUp32() and HighBitSetRoundUp64() functions
for calculating the last parameter ("SizeExponent") of SetIoPadding() and
SetMmioPadding().

Put the new functions to use when requesting the default reservations. (In
order to be consistent with a later patch, "SizeExponent" is calculated
for SetIoPadding() with HighBitSetRoundUp64().)

Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Marcel Apfelbaum <marcel@redhat.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2017-10-03 16:07:37 +02:00
Laszlo Ersek a980324709 OvmfPkg/PciHotPlugInitDxe: generalize RESOURCE_PADDING composition
PciHotPlugInitDxe has a static variable called "mPadding" (of type
RESOURCE_PADDING), which describes two constant resource reservations:

- MmioPadding: 2MB of non-prefetchable (hence 32-bit) MMIO space,

- IoPadding: 512B of IO space.

In the GetResourcePadding() member function of
EFI_PCI_HOT_PLUG_INIT_PROTOCOL, the driver outputs a dynamically allocated
verbatim copy of "mPadding", for PciBusDxe to consume in its
ApplyResourcePadding() function.

In a later patch, we're going to compose the set of resource reservations
dynamically, based on QEMU hints. Generalize the RESOURCE_PADDING
structure so that we may generate (or not generate) each resource type
individually:

- Replace the named "MmioPadding" and "IoPadding" fields in
  RESOURCE_PADDING with an array of descriptors,

- remove "mPadding",

- in GetResourcePadding(), request the same (default) reservations as
  before, as if we attempted and failed to fetch the QEMU hints.

Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Marcel Apfelbaum <marcel@redhat.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2017-10-03 16:07:35 +02:00
Laszlo Ersek c18ac9fbcc OvmfPkg/PciHotPlugInitDxe: clean up addr. range for non-prefetchable MMIO
The non-prefetchable MMIO aperture of a bridge can never fall outside of
the 32-bit address space. Namely, the MemoryBase and MemoryLimit fields in
PCI_BRIDGE_CONTROL_REGISTER have type UINT16, and based on the PCI-to-PCI
Bridge Architecture Spec, Chapter 3.2, the actual MMIO aperture is
determined as in:

NonPrefetchMemoryBase  = (((MemoryBase  & 0xFFF0u) >> 4) << 20) | 0x00000
NonPrefetchMemoryLimit = (((MemoryLimit & 0xFFF0u) >> 4) << 20) | 0xFFFFF

In "OvmfPkg/PciHotPlugInitDxe", the
"mPadding.MmioPadding.AddrSpaceGranularity" field is currently initialized
to 64. According to the above, this is useless generality: a
non-prefetchable MMIO reservation may only be satisfied from 32-bit
address space. Update the field to 32.

In practice this change makes no difference, because PciBusDxe already
enforces the 32-bit limitation when it sees "non-prefetchable" from
(SpecificFlag==0). Quoting commit 8aba40b792 ("OvmfPkg: add
PciHotPlugInitDxe", 2016-06-30): "regardless of our request for 64-bit
MMIO reservation, it is downgraded to 32-bit".

(See the Platform Init Spec 1.6, Volume 5,
- Table 8. "ACPI 2.0 & 3.0 QWORD Address Space Descriptor Usage", and
- Table 11. "Memory Resource Flag (Resource Type = 0) Usage",
for an explanation of the "mPadding.MmioPadding" fields.)

Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Marcel Apfelbaum <marcel@redhat.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Fixes: 8aba40b792
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2017-10-03 16:07:33 +02:00
Laszlo Ersek 91231fc2ff OvmfPkg/PciHotPlugInitDxe: clean up protocol usage comment
The driver always produces an instance of the
EFI_PCI_HOT_PLUG_INIT_PROTOCOL. The "SOMETIMES_PRODUCES" remark is an
oversight from the original v1->v2 patch update; v2 should have stated
"ALWAYS_PRODUCES":

http://mid.mail-archive.com/1468242274-12686-5-git-send-email-lersek@redhat.com

> Notes:
>     v2:
>     - drop the PcdPciBusHotplugDeviceSupport check, and the PcdLib
>       dependency with it [Jordan]

Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Marcel Apfelbaum <marcel@redhat.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Fixes: 8aba40b792
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2017-10-03 16:07:31 +02:00
Laszlo Ersek bdf73b57f2 OvmfPkg/IndustryStandard: define PCI Capabilities for QEMU's PCI Bridges
QEMU has recently gained the ability to provide various hints about its
PCI bridges. The hints take the form of vendor-specific PCI capabilities.
Define macros and types under "OvmfPkg/Include/IndustryStandard" to
describe these capabilities.

The definitions correspond to "docs/pcie_pci_bridge.txt" in the QEMU tree.
Said documentation was added in the last commit of the following series:

  a35fe226558a hw/pci: introduce pcie-pci-bridge device
  70e1ee59bb94 hw/pci: introduce bridge-only vendor-specific capability to
               provide some hints to firmware
  226263fb5cda hw/pci: add QEMU-specific PCI capability to the Generic PCI
               Express Root Port
  c1800a162765 docs: update documentation considering PCIE-PCI bridge

We are going to parse the Resource Reservation Capability in
OvmfPkg/PciHotPlugInitDxe, and return the reservation requests to
PciBusDxe.

Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Marcel Apfelbaum <marcel@redhat.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2017-10-03 16:07:29 +02:00
Laszlo Ersek d83defe0df OvmfPkg/VirtioNetDxe: log debug message in VirtioNetExitBoot()
The other four virtio device drivers (VirtioBlkDxe, VirtioGpuDxe,
VirtioRngDxe, VirtioScsiDxe) log such messages at this point; follow suit.

Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2017-09-22 15:01:51 +02:00
Laszlo Ersek 53b55831e0 OvmfPkg/VirtioNetDxe: document Rx/Tx allocs and mappings on Init/Shutdown
Document the following actions on the

  EfiSimpleNetworkStarted <-> EfiSimpleNetworkInitialized

state transitions:

* from commit 46b11f00ac ("OvmfPkg/VirtioNetDxe: alloc RxBuf using
  AllocateSharedPages()", 2017-09-14):

  VirtioNetInitRx ->
  { VirtIo->AllocateSharedPages, VirtioMapAllBytesInSharedBuffer }

  VirtioNetShutdownRx ->
  { VirtIo->UnmapSharedBuffer, VirtIo->FreeSharedPages }

* from commit 891f016c1b ("OvmfPkg/VirtioNetDxe: dynamically alloc
  transmit header", 2017-09-14):

  VirtioNetInitTx ->
  { VirtIo->AllocateSharedPages, VirtioMapAllBytesInSharedBuffer }

  VirtioNetShutdownTx ->
  { VirtIo->UnmapSharedBuffer, VirtIo->FreeSharedPages }

Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2017-09-22 15:01:29 +02:00
Laszlo Ersek f9c59fa44a OvmfPkg/QemuBootOrderLib: recognize "usb-storage" devices in XHCI ports
The feature is primarily useful for modern AARCH64 guests that have no
built-in virtio block / SCSI drivers; as on "qemu-system-aarch64 -M virt",
there are no IDE or AHCI controllers that could be used as fallback. XHCI
is available in "-M virt" however, and because XHCI predates AARCH64 by
several years, said guests are expected to have built-in drivers for it.

Other device models ("usb-uas", "usb-bot") are out of scope for now,
similarly to USB1.x (UHCI) and USB2 (EHCI) host controllers, and similarly
to USB hubs (which are USB1.1 only). In particular, port mapping between
EHCI and companion UHCI controllers is very complex; it even leads to PCI
slot/function differences between the OpenFirmware device paths exported
by QEMU and the the UEFI device paths generated by edk2.

The number of ports on the XHCI controller defaults to 4, but it can be
raised via the "p3" property to 15. In addition, several XHCI controllers
can be grouped into a single-slot, multi-function PCI device. These allow
for a good number of usb-storage devices, while their desired boot order
remains recognizable to this patch.

In the example below, we create two XHCI controllers, grouped into PCI
slot 00:02 as functions 0 and 1. Both controllers are given 15 ports. We
attach a "usb-storage" device to controller 1 at port 3 (ports are 1-based
in QEMU, 0-based in edk2), and attach another "usb-storage" device to
controller 2 at port 9.

QEMU command line options (NB. they apply equally to aarch64/virt and
x86_64/{i440fx,q35}):

  -device qemu-xhci,id=xhci1,p3=15,addr=02.0,multifunction=on \
  -device qemu-xhci,id=xhci2,p3=15,addr=02.1 \
  \
  -drive id=disk1,if=none,format=qcow2,$DISK1_OPTIONS \
  -drive id=disk2,if=none,format=qcow2,$DISK2_OPTIONS \
  \
  -device usb-storage,drive=disk1,bus=xhci1.0,port=3,bootindex=1 \
  -device usb-storage,drive=disk2,bus=xhci2.0,port=9,bootindex=2 \

Libvirt domain XML fragment:

  <controller type='usb' index='1' model='qemu-xhci' ports='15'>
    <address type='pci'
     domain='0x0000' bus='0x00' slot='0x02' function='0x0'
     multifunction='on'/>
  </controller>
  <controller type='usb' index='2' model='qemu-xhci' ports='15'>
    <address type='pci'
     domain='0x0000' bus='0x00' slot='0x02' function='0x1'/>
  </controller>

  <disk type='file' device='disk'>
    <driver name='qemu' type='qcow2'/>
    <source file='...'/>
    <target dev='sda' bus='usb'/>
    <boot order='1'/>
    <address type='usb' bus='1' port='3'/>
  </disk>
  <disk type='file' device='disk'>
    <driver name='qemu' type='qcow2'/>
    <source file='...'/>
    <target dev='sdb' bus='usb'/>
    <boot order='2'/>
    <address type='usb' bus='2' port='9'/>
  </disk>

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
2017-09-22 14:54:35 +02:00
Laszlo Ersek 947f3737ab OvmfPkg/QemuVideoDxe/VbeShim: handle PAM1 register on Q35 correctly
In commit db27e9f3d8 ("OvmfPkg/LegacyRegion: Support legacy region
manipulation of Q35", 2016-03-15), Ray extended the
OvmfPkg/Csm/CsmSupportLib PAM register manipulation to Q35. However, we
missed that the same should be done to the QemuVideoDxe VBE Shim as well.

The omission has caused no problems in practice on Q35, because QEMU has
let us write to the ROM area, regardless of the PAM1 setting, all this
time. This has now changed with recent QEMU commit 208fa0e43645 ("pc: make
'pc.rom' readonly when machine has PCI enabled", 2017-07-28). The QEMU
commit exposes the OVMF bug when Windows 7 is started on Q35, using QEMU
2.10 -- the VBE Shim is no longer put in place and Windows 7 cannot find
it.

To remedy this, assign the "Pam1Address" local variable a PciLib address
that matches the board type (i440fx vs. q35).

Regarding the PcdLib dependency: QemuVideoDxe already uses PcdLib, both
directly (see "PcdDriverSupportedEfiVersion") and indirectly (e.g. via the
DxePciLibI440FxQ35 PciLib instance). Add PcdLib to [LibraryClasses] for
completeness.

Cc: Aleksei Kovura <alex3kov@zoho.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Igor Mammedov <imammedo@redhat.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Ref: https://bugs.launchpad.net/qemu/+bug/1715700
Reported-by: Aleksei Kovura <alex3kov@zoho.com>
Special-thanks-to: Gerd Hoffmann <kraxel@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Aleksei Kovura <alex3kov@zoho.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2017-09-20 20:25:19 +02:00
Laszlo Ersek ce461ae240 OvmfPkg/QemuVideoDxe/VbeShim: rename Status to Segment0AllocationStatus
This clarifies the purpose of the local variable in InstallVbeShim().

Cc: Aleksei Kovura <alex3kov@zoho.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Igor Mammedov <imammedo@redhat.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Ref: https://bugs.launchpad.net/qemu/+bug/1715700
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Aleksei Kovura <alex3kov@zoho.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2017-09-20 20:25:15 +02:00
Laszlo Ersek ba1d245f1d OvmfPkg/CsmSupportLib: move PAM register addresses to IndustryStandard
* Introduce the PIIX4_PAM* and MCH_PAM* macros under
  "OvmfPkg/Include/IndustryStandard". These macros capture the PAM
  register offsets (in PCI config space) on the respective Memory
  Controller B/D/F, from the respective data sheets.

* Under IndustryStandard, introduce the PMC_REGISTER_PIIX4() macro for
  PIIX4. (For Q35, we already have DRAMC_REGISTER_Q35().) In both cases,
  the B/D/F is 0/0/0.

* Under CsmSupportLib, replace the "PAMRegOffset" field (UINT8) in the
  PAM_REGISTER_VALUE structure with "PAMRegPciLibAddress" (UINTN). The new
  field contains the return value of the PCI_LIB_ADDRESS() macro.

* Under CsmSupportLib, replace the "mRegisterValues440" elements as
  follows:

    REG_PAMx_OFFSET_440, ReadEnableData, WriteEnableData
    -->
    PMC_REGISTER_PIIX4 (PIIX4_PAMx), ReadEnableData, WriteEnableData

* Under CsmSupportLib, replace the "mRegisterValuesQ35" elements as
  follows:

    REG_PAMx_OFFSET_Q35, ReadEnableData, WriteEnableData
    -->
    DRAMC_REGISTER_Q35 (MCH_PAMx), ReadEnableData, WriteEnableData

* Under CsmSupportLib, update the register address calculations as follows
  (for all of PciOr8(), PciAnd8() and PciRead8()):

    PCI_LIB_ADDRESS (
      PAM_PCI_BUS,
      PAM_PCI_DEV,
      PAM_PCI_FUNC,
      mRegisterValues[Index].PAMRegOffset
      )
    -->
    mRegisterValues[Index].PAMRegPciLibAddress

* Under CsmSupportLib, remove the PAM_PCI_* and REG_PAM*_OFFSET_* macros.

Technically speaking, these changes could be split into three patches
(IndustryStandard macro additions, CsmSupportLib code updates,
CsmSupportLib macro removals). However, the patch is not big, and in this
case it is actually helpful to present the code movement / refactoring in
one step, for easier verification.

Cc: Aleksei Kovura <alex3kov@zoho.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Igor Mammedov <imammedo@redhat.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Ruiyu Ni <ruiyu.ni@intel.com>
Ref: https://bugs.launchpad.net/qemu/+bug/1715700
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Aleksei Kovura <alex3kov@zoho.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2017-09-20 20:24:26 +02:00
Brijesh Singh f60ed5ab7f OvmfPkg/VirtioNetDxe: negotiate VIRTIO_F_IOMMU_PLATFORM
VirtioNetDxe driver has been updated to use IOMMU-like member functions
from VIRTIO_DEVICE_PROTOCOL to translate the system physical address to
device address. We do not need to do anything special when
VIRTIO_F_IOMMU_PLATFORM bit is present hence treat it in parallel with
VIRTIO_F_VERSION_1.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
2017-09-14 23:54:20 +02:00
Brijesh Singh 8fa54a8a94 OvmfPkg/VirtioNetDxe: map caller-supplied Tx packet to device-address
When device is behind the IOMMU, driver is require to pass the device
address of caller-supplied transmit buffer for the bus master operations.

The patch uses VirtioNetMapTxBuf() to map caller-supplied Tx packet to a
device-address and enqueue the device address in VRING for transfer and
perform the reverse mapping when transfer is completed so that we can
return the caller-supplied buffer.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
2017-09-14 23:54:18 +02:00
Brijesh Singh bd114d9f77 OvmfPkg/VirtioNetDxe: add Tx packet map/unmap helper functions
When device is behind IOMMU, driver is require to pass the device address
of TxBuf in the Tx VRING. The patch adds helper functions and data
structure to map and unmap the TxBuf system physical address to a device
address.

Since the TxBuf is returned back to caller from VirtioNetGetStatus() hence
we use OrderedCollection interface to save the TxBuf system physical to
device address mapping. After the TxBuf is succesfully transmitted
VirtioNetUnmapTxBuf() does the reverse lookup in OrderedCollection data
structure to get the system physical address of TxBuf for a given device
address.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
2017-09-14 23:54:15 +02:00
Brijesh Singh 76ad23ca82 OvmfPkg/VirtioNetDxe: update TechNotes
In next patches we will update Virtio transmit to use the device-mapped
address of the caller-supplied packet. The patch documents the new model.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
2017-09-14 23:54:12 +02:00
Brijesh Singh 891f016c1b OvmfPkg/VirtioNetDxe: dynamically alloc transmit header
Each network packet is submitted for transmission by pushing the head
descriptor of a two-part descriptor chain to the Available Ring of the
TX queue. VirtioNetInitTx() sets up the the descriptor chains for all
queueable packets in advance, and points all the head descriptors to the
same shared, never modified, VIRTIO_1_0_NET_REQ header object (or its
initial VIRTIO_NET_REQ sub-object, dependent on virtio version).
VirtioNetInitTx() currently uses the header object's system physical
address for populating the head descriptors.

When device is behind the IOMMU, VirtioNet driver is required to provide
the device address of VIRTIO_1_0_NET_REQ header. In this patch we
dynamically allocate the header using AllocateSharedPages() and map with
BusMasterCommonBuffer so that header can be accessed by both processor
and the device.

We map the header object for CommonBuffer operation because, in order to
stick with the current code order, we populate the head descriptors with
the header's device address first, and fill in the header itself second.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
2017-09-14 23:54:10 +02:00
Brijesh Singh 46b11f00ac OvmfPkg/VirtioNetDxe: alloc RxBuf using AllocateSharedPages()
When device is behind the IOMMU, VirtioNetDxe is required to use the
device address in bus master operations. RxBuf is allocated using
AllocatePool() which returns the system physical address.

The patch uses VIRTIO_DEVICE_PROTOCOL.AllocateSharedPages() to allocate
the RxBuf and map with VirtioMapAllBytesInSharedBuffer() so that we can
obtain the device address for RxBuf.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
2017-09-14 23:54:07 +02:00
Brijesh Singh 940baec09c OvmfPkg/VirtioNetDxe: map VRINGs using VirtioRingMap()
When device is behind the IOMMU then driver need to pass the device
address when programing the bus master. The patch uses VirtioRingMap() to
map the VRING system physical address[es] to device address[es].

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
2017-09-14 23:54:05 +02:00
Brijesh Singh 55dd5a673b OvmfPkg/VirtioNetDxe: add helper VirtioNetUninitRing()
Consolidate the virtio VRING resource cleanup into VirtioNetUninitRing().

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
2017-09-14 23:53:46 +02:00
Laszlo Ersek 5dfba97c4d OvmfPkg/SataControllerDxe: log informative message at DEBUG_INFO level
When a UEFI_DRIVER attempts to open a protocol interface with BY_DRIVER
attribute that it already has open with BY_DRIVER attribute,
OpenProtocol() returns EFI_ALREADY_STARTED. This is not an error. The
UEFI-2.7 spec currently says,

> EFI_ALREADY_STARTED -- Attributes is BY_DRIVER and there is an item on
>                        the open list with an attribute of BY_DRIVER
>                        whose agent handle is the same as AgentHandle.

(In fact it is so much an expected condition that recent USWG Mantis
ticket <https://mantis.uefi.org/mantis/view.php?id=1815> will codify its
additional edk2-specific behavior, namely to output the protocol interface
at once.)

Downgrade the log mask for this one condition to DEBUG_INFO, in
SataControllerStart(). This will match the log mask of the other two
informative messages in this function, "SataControllerStart START", and
"SataControllerStart END status = %r" (at which point Status can only be
EFI_SUCCESS).

Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
2017-09-11 22:39:32 +02:00
Laszlo Ersek 837d9eea7d OvmfPkg/PlatformBootManagerLib: log informative message at DEBUG_INFO lvl
"Boot Mode:%x" is an informative message, not an error report. Set its
debug mask to DEBUG_INFO.

Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
2017-09-11 22:39:32 +02:00
Laszlo Ersek 7707c9fd69 OvmfPkg/PlatformPei: log informative message at DEBUG_INFO level
"Platform PEIM Loaded" is an informative message, not an error report. Set
its debug mask to DEBUG_INFO.

Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
2017-09-11 22:39:31 +02:00
Laszlo Ersek 80886a6953 OvmfPkg/PlatformDebugLibIoPort: write messages with IoWriteFifo8()
Since commit 19c6d9feaa ("MdePkg: Expand BaseIoLibIntrinsic (IoLib
class) library", 2017-01-14), IoWriteFifo8() has been widely available to
modules. Use it to print debug messages and assertion failures to the QEMU
debug port, rather than open-coded loops.

In the general case this speeds up logging, because debug messages will
now trap to QEMU once per message (as opposed to once per character), due
to "REP OUTSB" in "MdePkg/Library/BaseIoLibIntrinsic/*/IoFifoSev.nasm".

In SEV guests, there is no speedup (SEV doesn't support the REP prefix).
SEV is detected internally to BaseIoLibIntrinsic.

Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Acked-by: Brijesh Singh <brijesh.singh@amd.com>
2017-09-11 22:28:25 +02:00
Paulo Alcantara f5566d1530 OvmfPkg: Enable UDF file system support
This patch enables UDF file system support by default.

Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Paulo Alcantara <pcacjr@zytor.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>
2017-09-08 20:42:51 +02:00
Laszlo Ersek 7aee391fa3 OvmfPkg/IoMmuDxe: unmap all IOMMU mappings at ExitBootServices()
Register an ExitBootServices() callback that tears down all IOMMU
mappings, without modifying the UEFI memory map.

The trick is that in the ExitBootServices() callback, we don't immediately
do the work; instead we signal another (private) event.

Normally the dispatch order of ExitBootServices() callbacks is unspecified
(within the same task priority level anyway). By queueing another
function, we delay the unmapping until after all PciIo and Virtio drivers
abort -- in their own ExitBootServices() callbacks -- the pending DMA
operations of their respective controllers.

Furthermore, the fact that IoMmuUnmapWorker() rewrites client-owned memory
when it unmaps a Write or CommonBuffer bus master operation, is safe even
in this context. The existence of any given "MapInfo" in "mMapInfos"
implies that the client buffer pointed-to by "MapInfo->CryptedAddress" was
live when ExitBootServices() was entered. And, after entering
ExitBootServices(), nothing must have changed the UEFI memory map, hence
the client buffer at "MapInfo->CryptedAddress" still exists.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
2017-09-08 20:24:06 +02:00
Laszlo Ersek 550acd08e5 OvmfPkg/IoMmuDxe: generalize IoMmuUnmap() to IoMmuUnmapWorker()
IoMmuUnmapWorker() is identical to IoMmuUnmap(), it just takes an
additional BOOLEAN parameter called "MemoryMapLocked".  If the memory map
is locked, IoMmuUnmapWorker() does its usual job, but it purposely leaks
memory rather than freeing it. This makes it callable from
ExitBootServices() context.

Turn IoMmuUnmap() into a thin wrapper around IoMmuUnmapWorker() that
passes constant FALSE for "MemoryMapLocked".

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
2017-09-08 20:24:04 +02:00
Laszlo Ersek 9ed745b967 OvmfPkg/IoMmuDxe: track all mappings
The "mRecycledMapInfos" list implements an internal pool of unused
MAP_INFO structures between the IoMmuUnmap() and IoMmuMap() functions. The
original goal was to allow IoMmuUnmap() to tear down CommonBuffer mappings
without releasing any memory: IoMmuUnmap() would recycle the MAP_INFO
structure to the list, and IoMmuMap() would always check the list first,
before allocating a brand new MAP_INFO structure.

In one of the following patches, we'll change OvmfPkg/IoMmuDxe so that it
unmaps all existent bus master operations (CommonBuffer, Read, Write) at
ExitBootServices(), strictly after the individual device drivers abort
pending DMA on the devices they manage, in their own ExitBootServices()
notification functions.

For this, rename and repurpose the list to track all live mappings.

This means that IoMmuUnmap() will always release a MAP_INFO structure
(even when cleaning up a CommonBuffer operation). That's fine (for now),
because device drivers are no longer expected to call Unmap() in their
ExitBootServices() notification functions.

In theory, we could also move the allocation and freeing of the stash
buffer from IoMmuAllocateBuffer() and IoMmuFreeBuffer(), respectively, to
IoMmuMap() and IoMmuUnmap(). However, this would require allocating and
freeing a stash buffer in *both* IoMmuMap() and IoMmuUnmap(), as
IoMmuMap() performs in-place decryption for CommonBuffer operations, and
IoMmuUnmap() performs in-place encryption for the same.

By keeping the stash buffer allocation as-is, not only do we keep the code
almost fully undisturbed, but

- we also continue to guarantee that IoMmuUnmap() succeeds: allocating a
  stash buffer in IoMmuUnmap(), for in-place encryption after a
  CommonBuffer operation, could fail;

- we also keep IoMmuUnmap() largely reusable for ExitBootServices()
  callback context: allocating a stash buffer in IoMmuUnmap() would simply
  be forbidden in that context.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
2017-09-08 20:24:01 +02:00
Laszlo Ersek bf99bdd1f7 OvmfPkg/VirtioScsiDxe: don't unmap VRING at ExitBootServices()
In one of the following patches, we'll change OvmfPkg/IoMmuDxe so that it
unmaps all existent bus master operations (CommonBuffer, Read, Write) at
ExitBootServices(), strictly after the individual device drivers abort
pending DMA on the devices they manage, in their own ExitBootServices()
notification functions.

In preparation, remove the explicit
VIRTIO_DEVICE_PROTOCOL.UnmapSharedBuffer() call from VirtioScsiExitBoot(),
originally added in commit fc2168feb2 ("OvmfPkg/VirtioScsiDxe: map VRING
using VirtioRingMap()", 2017-08-31).

Add a DEBUG message so we can observe the ordering between
VirtioScsiExitBoot() and the upcoming cleanup of mappings in
OvmfPkg/IoMmuDxe.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
2017-09-08 20:23:58 +02:00
Laszlo Ersek 21e57370fc OvmfPkg/VirtioRngDxe: don't unmap VRING at ExitBootServices()
In one of the following patches, we'll change OvmfPkg/IoMmuDxe so that it
unmaps all existent bus master operations (CommonBuffer, Read, Write) at
ExitBootServices(), strictly after the individual device drivers abort
pending DMA on the devices they manage, in their own ExitBootServices()
notification functions.

In preparation, remove the explicit
VIRTIO_DEVICE_PROTOCOL.UnmapSharedBuffer() call from VirtioRngExitBoot(),
originally added in commit 0a568ccbcb ("OvmfPkg/VirtioRngDxe: map host
address to device address", 2017-08-23).

Add a DEBUG message so we can observe the ordering between
VirtioRngExitBoot() and the upcoming cleanup of mappings in
OvmfPkg/IoMmuDxe.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
2017-09-08 20:23:56 +02:00
Laszlo Ersek 8ddd12e53f OvmfPkg/VirtioGpuDxe: don't unmap VRING & BackingStore at ExitBootServices
In one of the following patches, we'll change OvmfPkg/IoMmuDxe so that it
unmaps all existent bus master operations (CommonBuffer, Read, Write) at
ExitBootServices(), strictly after the individual device drivers abort
pending DMA on the devices they manage, in their own ExitBootServices()
notification functions.

In preparation, remove the explicit
VIRTIO_DEVICE_PROTOCOL.UnmapSharedBuffer() calls from VirtioGpuExitBoot(),
originally added in commit 9bc5026c19 ("OvmfPkg/VirtioGpuDxe: map VRING
for bus master common buffer operation", 2017-08-26) and commit
f10ae92366 ("OvmfPkg/VirtioGpuDxe: map backing store to bus master
device address", 2017-08-26).

Add a DEBUG message so we can observe the ordering between
VirtioGpuExitBoot() and the upcoming cleanup of mappings in
OvmfPkg/IoMmuDxe.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
2017-09-08 20:23:53 +02:00
Laszlo Ersek 5659ec3fa9 OvmfPkg/VirtioBlkDxe: don't unmap VRING at ExitBootServices()
In one of the following patches, we'll change OvmfPkg/IoMmuDxe so that it
unmaps all existent bus master operations (CommonBuffer, Read, Write) at
ExitBootServices(), strictly after the individual device drivers abort
pending DMA on the devices they manage, in their own ExitBootServices()
notification functions.

In preparation, remove the explicit
VIRTIO_DEVICE_PROTOCOL.UnmapSharedBuffer() call from VirtioBlkExitBoot(),
originally added in commit 1916513047 ("OvmfPkg/VirtioBlkDxe: map VRING
using VirtioRingMap()", 2017-08-27).

Add a DEBUG message so we can observe the ordering between
VirtioBlkExitBoot() and the upcoming cleanup of mappings in
OvmfPkg/IoMmuDxe.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
2017-09-08 20:23:47 +02:00
Ge Song 89796c69d9 OvmfPkg/SecMain: Fix stack switching to permanent memory
In earlier PEI stage, temporary memory at PcdOvmfSecPeiTempRamBase is
employed as stack and heap. We move them to the new room and do some
relocation fixup when permanent memory becomes available.
TemporaryRamMigration() is responsible for switching the stack.

Before entering TemporaryRamMigration(), Ebp/Rbp is populated with the
content of Esp/Rsp and used as frame pointer.

After the execution of SetJump/LongJump, stack migrates to new position
while the context keeps unchanged.

But when TemporaryRamMigration() exits, Esp/Rsp is filled with
the content of Ebp/Rbp to destroy this stack frame.

The result is, stack switches back to previous temporary memory.

When permanent memory becomes available, modules that have registered
themselves for shadowing will be scheduled to execute. Some of them
need to consume more memory(heap/stack). Contrast to temporary stack,
permanent stack possesses larger space.

The potential risk is overflowing the stack if stack staying in
temporary memory. When it happens, system may crash during S3 resume.

More detailed information:
> (gdb) disassemble /r
> Dump of assembler code for function TemporaryRamMigration:
>   0x00000000fffcd29c <+0>:	55	push   %rbp
>   0x00000000fffcd29d <+1>:	48 89 e5	mov    %rsp,%rbp
>   0x00000000fffcd2a0 <+4>:	48 81 ec 70 01 00 00	sub
> $0x170,%rsp
>    ...
>    ...
>    0x00000000fffcd425 <+393>:	e8 80 10 00 00	callq  0xfffce4aa
> <SaveAndSetDebugTimerInterrupt>
> => 0x00000000fffcd42a <+398>:	b8 00 00 00 00	mov    $0x0,%eax
>    0x00000000fffcd42f <+403>:	c9	leaveq
>    0x00000000fffcd430 <+404>:	c3	retq
> End of assembler dump.

See the description of leave(opcode: c9), from
Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 2A

"Releases the stack frame set up by an earlier ENTER instruction. The
LEAVE instruction copies the frame pointer (in the EBP register) into
the stack pointer register (ESP), which releases the stack space
allocated to the stack frame. The old frame pointer (the frame pointer
for the calling procedure that was saved by the ENTER instruction) is
then popped from the stack into the EBP register, restoring the calling
procedure’s stack frame."

To solve this, update Ebp/Rbp too when Esp/Rsp is updated

Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ge Song <ge.song@hxt-semitech.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2017-09-06 10:07:16 -07:00
Laszlo Ersek db52890926 OvmfPkg/VirtioGpuDxe: negotiate VIRTIO_F_IOMMU_PLATFORM
VirtioGpuDxe is now IOMMU-clean; it translates system memory addresses to
bus master device addresses. Negotiate VIRTIO_F_IOMMU_PLATFORM in parallel
with VIRTIO_F_VERSION_1. (Note: the VirtIo GPU device, and this driver,
are virtio-1.0 only (a.k.a. "modern-only").)

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
2017-09-01 14:28:28 +02:00
Laszlo Ersek f10ae92366 OvmfPkg/VirtioGpuDxe: map backing store to bus master device address
VirtioGpuDxe is a UEFI Bus driver (not a Device driver). This is because a
UEFI graphics driver is expected to produce its GraphicsOutput protocol
instance(s) on new child handle(s) of the video controller handle, one
child handle (plus GOP) per video output (or, one child handle plus GOP
per combination of multiple video outputs).

In VirtioGpuDxe, we support a single VirtIo GPU head (scanout), namely
head#0. This means that, with regard to a specific VirtIo GPU device, the
driver may be in one of three states, at any time:

[1] VirtioGpuDxe has not bound the device at all,

[2] VirtioGpuDxe has bound the device, but not produced the sole child
    handle for head#0,

[3] VirtioGpuDxe has bound the device, and produced the sole child handle
    for head#0, with a GOP instance on the child handle.

(Which state the driver is in wrt. a given VirtIo GPU device depends on
the VirtioGpuDriverBindingStart() / VirtioGpuDriverBindingStop()
invocations issued by the ConnectController() / DisconnectController()
boot services. In turn those come from BDS or e.g. the UEFI shell.)

The concept of "current video mode" is technically tied to the GOP (i.e.,
the child handle, state [3] only), not the VirtIo GPU controller handle.
This is why we manage the storage that backs the current video mode in our
EFI_GRAPHICS_OUTPUT_PROTOCOL.SetMode() member implementation.

GopSetMode() is first called *internally*, when we enter state [3] (that
is, when we produce the child handle + GOP on it):

  VirtioGpuDriverBindingStart() [DriverBinding.c]
    InitVgpuGop()               [DriverBinding.c]
      VgpuGop->Gop.SetMode()    [Gop.c]

When this happens, we allocate the backing store *without* having a
preexistent backing store (due to no preexistent video mode and GOP).
Skipping VirtIo GPU details not relevant for this patch, we just note that
the backing store is exposed *permanently* to the VirtIo GPU device, with
the RESOURCE_ATTACH_BACKING command.

When external clients call the EFI_GRAPHICS_OUTPUT_PROTOCOL.Blt() member
function -- called GopBlt() in this driver --, in state [3], the function
operates on the backing store, and sends only small messages to the VirtIo
GPU device.

When external clients call GopSetMode() for switching between video modes
-- in state [3] --, then

- a new backing store is allocated and exposed to the device (attached to
  a new host-side VirtIo GPU resource),

- head#0 is flipped to the new backing store,

- on success, the ReleaseGopResources() function both detaches the
  previous backing store from the VirtIo GPU device, an releases it. The
  new backing store address and size are saved in our GOP object. (In
  other words, we "commit" to the new video mode.)

When the DisconnectController() boot service asks us to leave state [3] --
we can leave it directly only for state [2] --, then the
ReleaseGopResources() function is called on a different path:

  VirtioGpuDriverBindingStop() [DriverBinding.c]
    UninitVgpuGop()            [DriverBinding.c]
      ReleaseGopResources()    [Gop.c]

In this case, the backing store being released is still in use (we're not
leaving it for a new mode -- head#0 has not been flipped "away" from it),
so in ReleaseGopResources() we disable head#0 first.

(The ReleaseGopResources() function is called the same way on the error
path in InitVgpuGop(), if the first -- internal -- VgpuGop->Gop.SetMode()
call succeeds, but the rest of InitVgpuGop() fails.)

Based on the above, for IOMMU-compatibility,

- in GopSetMode(), don't just allocate, but also map the backing store of
  the nascent video mode to a device address, for bus master common buffer
  operation,

- (the VirtioGpuAllocateZeroAndMapBackingStore() helper function
  introduced in the last patch takes care of zeroing internally,)

- pass the device address to the VirtIo GPU device in the
  RESOURCE_ATTACH_BACKING command,

- if GopSetMode() succeeds, save the mapping token,

- if GopSetMode() fails, don't just free but also unmap the still-born
  backing store,

- in ReleaseGopResources(), don't just free but also unmap the backing
  store -- which is the previous backing store if we're mode-switching,
  and the current backing store if we're leaving state [3].

Finally, ExitBootServices() may be called when the driver is in either
state [1], [2] or [3], wrt. a given VirtIo GPU device. (Of course we are
only notified in states [2] and [3].) If we get the notification in state
[3], then the current video mode's backing store has to be unmapped, but
not released. (We must not change the UEFI memory map.)

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
2017-09-01 14:28:22 +02:00
Laszlo Ersek 5c8f091bd8 OvmfPkg/VirtioGpuDxe: helpers for backing store (de)allocation+(un)mapping
Introduce the VirtioGpuAllocateZeroAndMapBackingStore() and
VirtioGpuUnmapAndFreeBackingStore() helper functions. These functions tie
together the allocation, zeroing and mapping, and unmapping and
deallocation, respectively, of memory that the virtio GPU will permanently
reference after receiving the RESOURCE_ATTACH_BACKING command.

With these functions we can keep the next patch simpler -- the GOP
implementation in "Gop.c" retains its error handling structure, and
remains oblivious to VIRTIO_DEVICE_PROTOCOL and VirtioLib.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
2017-09-01 14:28:20 +02:00
Laszlo Ersek 5409c6abc8 OvmfPkg/VirtioGpuDxe: take EFI_PHYSICAL_ADDRESS in ResourceAttachBacking()
The RESOURCE_ATTACH_BACKING virtio GPU command assigns guest-side backing
pages to a host-side resource that was created earlier with the
RESOURCE_CREATE_2D command.

We compose the RESOURCE_ATTACH_BACKING command in the
VirtioGpuResourceAttachBacking() function. Currently this function takes
the parameter

  IN VOID *FirstBackingPage

This is only appropriate as long as we pass a (guest-phys) system memory
address to the device. In preparation for a mapped bus master device
address, change the above parameter to

  IN EFI_PHYSICAL_ADDRESS BackingStoreDeviceAddress

In order to keep the current call site functional, move the (VOID*) to
(UINTN) conversion out of the function, to the call site.

The "Request.Entry.Addr" field already has type UINT64.

This patch is similar to commit 4b725858de ("OvmfPkg/VirtioLib: change
the parameter of VirtioAppendDesc() to UINT64", 2017-08-23).

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
2017-09-01 14:28:17 +02:00
Laszlo Ersek 067b648332 OvmfPkg/VirtioGpuDxe: map virtio GPU command objects to device addresses
Every virtio GPU command used by VirtioGpuDxe is synchronous and formatted
as a two-descriptor chain: request, response. The internal workhorse
function that all the command-specific functions call for such messaging
is VirtioGpuSendCommand().

In VirtioGpuSendCommand(), map the request from system memory to bus
master device address for BusMasterRead operation, and map the response
from system memory to bus master device address for BusMasterWrite
operation.

Pass the bus master device addresses to VirtioAppendDesc(). (See also
commit 4b725858de, "OvmfPkg/VirtioLib: change the parameter of
VirtioAppendDesc() to UINT64", 2017-08-23.)

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
2017-09-01 14:28:15 +02:00
Laszlo Ersek 9bc5026c19 OvmfPkg/VirtioGpuDxe: map VRING for bus master common buffer operation
VirtioGpuDxe uses one virtio ring, for VIRTIO_GPU_CONTROL_QUEUE.

Map it for bus master common buffer operation with VirtioRingMap(), so
that it can be accessed equally by both guest and hypervisor even if an
IOMMU is used. (VirtioRingInit() already allocates the ring suitably for
this, see commit b0338c5329, "OvmfPkg/VirtioLib: alloc VRING buffer with
AllocateSharedPages()", 2017-08-23).

Pass the resultant translation offset ("RingBaseShift"), from system
memory address to bus master device address, to VIRTIO_SET_QUEUE_ADDRESS.

Unmap the ring in all contexts where the ring becomes unused (these
contexts are mutually exclusive):

- in VirtioGpuInit(): the ring has been mapped, but we cannot complete the
  virtio initialization for another reason,

- in VirtioGpuUninit(): the virtio initialization has succeeded, but
  VirtioGpuDriverBindingStart() fails for another reason, or
  VirtioGpuDriverBindingStop() unbinds the device after use,

- in VirtioGpuExitBoot(): ExitBootServices() is called after
  VirtioGpuDriverBindingStart() has successfully bound the device.
  (Unmapping the ring does not change the UEFI memory map.)

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
2017-09-01 14:27:28 +02:00
Laszlo Ersek 1afbb85f87 OvmfPkg/IoMmuDxe: IoMmuFreeBuffer(): clean up DEBUG message
Log all relevant IN parameters on entry. (There are only IN parameters.)
Beautify the format string.

Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
2017-09-01 14:20:47 +02:00
Laszlo Ersek 80ddd336da OvmfPkg/IoMmuDxe: IoMmuAllocateBuffer(): nicer and more informative DEBUGs
Log all relevant IN and IN OUT parameters on entry.

(Note that the HostAddress parameter is IN OUT rather than OUT due to
historical reasons. The "IN EFI_ALLOCATE_TYPE Type" parameter is now to be
ignored, but historically it could be set to AllocateMaxAddress for
example, and for that HostAddress had to be IN OUT.)

When exiting with success, log all relevant OUT parameters (i.e.,
HostAddress). Also log the new (internal) StashBuffer address, on which
IoMmuMap() and IoMmuUnmap() rely on, for BusMasterCommonBuffer operations
(in-place decryption and encryption, respectively).

Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
2017-09-01 14:20:45 +02:00
Laszlo Ersek a1d6a9dcda OvmfPkg/IoMmuDxe: IoMmuUnmap(): clean up DEBUG message
The only important external information for this function, and for the
human looking at the log, is the Mapping input parameter. Log it on entry.

Stop logging the contents of the MAP_INFO structure pointed-to by Mapping.
Thanks to the previous patch, we can now associate IoMmuUnmap() messages
with IoMmuMap() messages -- and thereby with MAP_INFO contents -- purely
via Mapping.

Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
2017-09-01 14:20:42 +02:00
Laszlo Ersek 2ad6ba80a1 OvmfPkg/IoMmuDxe: IoMmuMap(): log nicer and more informative DEBUG msgs
Log all relevant IN and IN OUT parameters on entry.

When exiting with success, log all relevant OUT and IN OUT parameters.
Don't log OUT and IN OUT parameters that are never set or changed after
entering the function (i.e., *NumberOfBytes).

Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
2017-09-01 14:20:40 +02:00
Laszlo Ersek d8d33741e8 OvmfPkg/BaseMemEncryptSevLib: fix typos in DEBUG messages
Replace "spliting" with "splitting".

Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
2017-09-01 14:20:37 +02:00
Laszlo Ersek 5597edfa8b OvmfPkg/BaseMemEncryptSevLib: clean up upper-case / lower-case in DEBUGs
Debug messages that start as natural (English) language phrases (after the
debug prefix) should uniformly begin with lower-case or upper-case. In
SetMemoryEncDec() we have a mixture now. Stick with lower-case.
(Upper-case is better for full sentences that also end with punctuation.)

Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
2017-09-01 14:20:35 +02:00
Laszlo Ersek 3728ea5a95 OvmfPkg/BaseMemEncryptSevLib: promote DEBUG_WARN levels to DEBUG_ERROR
In SetMemoryEncDec(), we have four locations where we (a) log a message on
the DEBUG_WARN level that says "ERROR", (b) return the status code
RETURN_NO_MAPPING right after.

These messages clearly describe actual errors (bad PML4, PDPE, PDE, PTE).
Promote their debug levels to DEBUG_ERROR, and remove the word "ERROR"
from the messages.

Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
2017-09-01 14:20:33 +02:00
Laszlo Ersek 631bd7e084 OvmfPkg/BaseMemEncryptSevLib: clean up debug logging of PhysicalAddress
In the SetMemoryEncDec() function, the way we currently report
PhysicalAddress is not uniform:

- mostly we say "for %lx",

- in one spot we say "at %lx" (even though the 2MB page being split does
  not live *at* PhysicalAddress, instead it maps PhysicalAddress),

- in another spot we don't log PhysicalAddress at all (when splitting a
  1GB page).

Unify this, using the format string "for Physical=0x%Lx".

Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
2017-09-01 14:20:30 +02:00
Laszlo Ersek 6c72134dff OvmfPkg/BaseMemEncryptSevLib: clean up DEBUG prefixes
The prefix for the SetMemoryEncDec() DEBUG messages should be

  "ModuleName:FunctionName: "

not

  "ModuleName:FunctionName "

Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
2017-09-01 14:20:27 +02:00
Laszlo Ersek 6692af92b1 OvmfPkg/BaseMemEncryptSevLib: break DEBUG calls to multiple lines
None of the DEBUG macro invocations in SetMemoryEncDec() fit on a single
line. Break them to multiple lines, for (a) conforming to the coding style
spec, (b) easier modification in later patches.

Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
2017-09-01 14:20:24 +02:00
Laszlo Ersek 70063aecde OvmfPkg/BaseMemEncryptSevLib: unify encrypt/decrypt DEBUG messages
Unify the debug messages between InternalMemEncryptSevSetMemoryEncrypted()
and InternalMemEncryptSevSetMemoryDecrypted().

Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
2017-09-01 14:19:43 +02:00
Brijesh Singh 17cbf7359f OvmfPkg/VirtioScsiDxe: negotiate VIRTIO_F_IOMMU_PLATFORM
VirtioScsiDxe driver has been updated to use IOMMU-like member functions
from VIRTIO_DEVICE_PROTOCOL to translate the system physical address to
device address. We do not need to do anything special when
VIRTIO_F_IOMMU_PLATFORM bit is present hence treat it in parallel with
VIRTIO_F_VERSION_1.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
2017-08-31 21:29:53 +02:00
Brijesh Singh 9d0d5050c7 OvmfPkg/VirtioScsiDxe: map virtio-scsi request and response buffers
When device is behind the IOMMU, driver is require to pass the device
address of virtio request, response and any memory referenced by those
request/response to the bus master.

The patch uses IOMMU-like member functions from VIRTIO_DEVICE_PROTOCOL to
map request and response buffers system physical address to the device
address.

- If the buffer need to be accessed by both the processor and a bus
  master then map with BusMasterCommonBuffer.

- If the buffer need to be accessed for a write operation by a bus master
  then map with BusMasterWrite.

  However, after a BusMasterWrite Unmap() failure, error reporting via
  EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET would be very complex,
  therefore we map such buffers too with BusMasterCommonBuffer.

- If the buffer need to be accessed for a read  operation by a bus master
  then map with BusMasterRead.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
[lersek@redhat.com: restore lost sentence/paragraph in commit message]
[lersek@redhat.com: reindent/reflow "InDataBuffer" comment block]
[lersek@redhat.com: cast arg, not result, of EFI_SIZE_TO_PAGES() to UINTN]
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
2017-08-31 21:28:26 +02:00
Brijesh Singh 1b15eb06c7 OvmfPkg/VirtioScsiDxe: add helper to create a fake host adapter error
When virtio request fails we return EFI_DEVICE_ERROR, as per the spec
EFI_EXT_SCSI_PASS_THRU_PROTOCOL.PassThru() member function is required
to implement elaborated error reporting.

The patch refactors out entire block of the code that creates the host
adapter error into a separate helper function (ReportHostAdapterError).

Suggested-by: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
[lersek@redhat.com: fix style & typo in ReportHostAdapterError() comment]
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
2017-08-31 21:01:31 +02:00
Brijesh Singh fc2168feb2 OvmfPkg/VirtioScsiDxe: map VRING using VirtioRingMap()
When device is behind the IOMMU then driver need to pass the device
address when programing the bus master. The patch uses VirtioRingMap() to
map the VRING system physical address to device address.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
2017-08-31 20:57:04 +02:00
Brijesh Singh ea8314e440 OvmfPkg/VirtioBlkDxe: Check the return status of unmap data buffer
when "RequestIsWrite" is FALSE -- i.e., the CPU wants data from
the device, we map "Buffer" for VirtioOperationBusMasterWrite. In
this case, checking the return status of

Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, BufferMapping);

is must. If the unmapping fails, then "Buffer" will not contain the
actual data from the device, and we must fail the request with
EFI_DEVICE_ERROR.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
[lersek@redhat.com: fix typos in subject]
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Laszlo Ersek <lersek@redhat.com>
2017-08-30 18:53:54 +02:00
Laszlo Ersek d431d8339e OvmfPkg/QemuFwCfgDxeLib: SEV: zero FW_CFG_DMA_ACCESS before decrypting it
There's a small window between

- AllocFwCfgDmaAccessBuffer() mapping the new FW_CFG_DMA_ACCESS object for
  common buffer operation (i.e., decrypting it), and

- InternalQemuFwCfgDmaBytes() setting the fields of the object.

In this window, earlier garbage in the object is "leaked" to the
hypervisor. So zero the object before we decrypt it.

(This commit message references AMD SEV directly, because QemuFwCfgDxeLib
is not *generally* enabled for IOMMU operation just yet, unlike our goal
for the virtio infrastructure. Instead, QemuFwCfgDxeLib uses
MemEncryptSevLib explicitly to detect SEV, and then relies on IOMMU
protocol behavior that is specific to SEV. At this point, this is by
design.)

Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2017-08-29 22:44:33 +02:00
Brijesh Singh dd4205f8ba OvmfPkg/VirtioBlkDxe: negotiate VIRTIO_F_IOMMU_PLATFORM
VirtioBlkDxe driver has been updated to use IOMMU-like member functions
from VIRTIO_DEVICE_PROTOCOL to translate the system physical address to
device address. We do not need to do anything special when
VIRTIO_F_IOMMU_PLATFORM bit is present hence treat it in parallel with
VIRTIO_F_VERSION_1.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
2017-08-28 11:00:14 +02:00
Brijesh Singh 3540f2cef5 Ovmfpkg/VirtioBlkDxe: map virtio-blk request and response buffers
When device is behind the IOMMU, driver is require to pass the device
address of virtio request, response and any memory referenced by those
request/response to the bus master.

The patch uses IOMMU-like member functions from VIRTIO_DEVICE_PROTOCOL to
map request and response buffers system physical address to the device
address.

- If the buffer need to be accessed by both the processor and a bus
  master then map with BusMasterCommonBuffer.

- If the buffer need to be accessed for a write operation by a bus master
  then map with BusMasterWrite.

- If the buffer need to be accessed for a read  operation by a bus master
  then map with BusMasterRead.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
2017-08-28 11:00:14 +02:00
Brijesh Singh 1916513047 OvmfPkg/VirtioBlkDxe: map VRING using VirtioRingMap()
When device is behind the IOMMU then driver need to pass the device
address when programing the bus master. The patch uses VirtioRingMap() to
map the VRING system physical address to device address.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
2017-08-28 11:00:14 +02:00
Laszlo Ersek 656ac0c7d8 Revert "OvmfPkg/build.sh: select the GCC49 toolchain settings for gcc-7.*"
This reverts commit ca56256d5e0b7e63325b049e90a6bd03f90e3598:

TianoCore BZ#671 <https://bugzilla.tianocore.org/show_bug.cgi?id=671> has
been fixed in commit 2f7f1e73c1 ("BaseTools: Add the missing -pie link
option in GCC tool chain", 2017-08-23), so we can return to the GCC5
toolchain with gcc-7.*.

Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2017-08-25 19:21:40 +02:00
Brijesh Singh 4bef13da00 OvmfPkg/VirtioRngDxe: negotiate VIRTIO_F_IOMMU_PLATFORM
VirtioRngDxe driver has been updated to use IOMMU-like member functions
from VIRTIO_DEVICE_PROTOCOL to translate the system physical address to
device address. We do not need to do anything special when
VIRTIO_F_IOMMU_PLATFORM bit is present hence treat it in parallel with
VIRTIO_F_VERSION_1.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
2017-08-25 16:19:57 +02:00
Brijesh Singh 4fb268029e OvmfPkg/Virtio10: define VIRTIO_F_IOMMU_PLATFORM feature bit
This feature indicates that the device is behind an IOMMU that translates
bus addresses from the device into physical addresses in memory.  If this
feature bit is set to 0, then the device emits physical addresses which
are not translated further, even though an IOMMU may be present.
see [1] for more infromation

[1] https://lists.oasis-open.org/archives/virtio-dev/201610/msg00121.html

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
2017-08-25 16:19:48 +02:00
Brijesh Singh 0a568ccbcb OvmfPkg/VirtioRngDxe: map host address to device address
patch maps the host address to a device address for buffers (including
rings, device specifc request and response pointed by vring descriptor,
and any further memory reference by those request and response).

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
[lersek@redhat.com: return EFI_DEVICE_ERROR if mapping fails in GetRNG]
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
2017-08-25 10:42:19 +02:00
Brijesh Singh 4b725858de OvmfPkg/VirtioLib: change the parameter of VirtioAppendDesc() to UINT64
The patch change the "BufferPhysAddr" parameter of VirtioAppendDesc()
from type UINTN to UINT64.

UINTN is appropriate as long as we pass system memory references. After
the introduction of bus master device addresses, that's no longer the case
in general. Should we implement "real" IOMMU support at some point, UINTN
could break in 32-bit builds of OVMF.

Suggested-by: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
[lersek@redhat.com: clarify commit message]
[lersek@redhat.com: balance parens in VirtioAppendDesc() comment blocks]
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
2017-08-25 10:42:19 +02:00
Brijesh Singh b0338c5329 OvmfPkg/VirtioLib: alloc VRING buffer with AllocateSharedPages()
The VRING buffer is a communication area between guest and hypervisor.
Allocate it using VIRTIO_DEVICE_PROTOCOL.AllocateSharedPages() so that
it can be mapped later with VirtioRingMap() for bi-directional access.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
[lersek@redhat.com: correct typo in VirtioRingInit() comment blocks]
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
2017-08-25 10:42:19 +02:00
Brijesh Singh fef6becb55 OvmfPkg/VirtioLib: add function to map VRING
Add a function to map the ring buffer with BusMasterCommonBuffer so that
ring can be accessed by both guest and hypervisor.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
[lersek@redhat.com: fix typo in commit message]
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
2017-08-25 10:42:19 +02:00
Brijesh Singh 60ee56295f OvmfPkg/Virtio10Dxe: add the RingBaseShift offset
virtio drivers use VIRTIO_DEVICE_PROTOCOL.MapSharedBuffer() to map the
ring buffer host address to a device address. If an IOMMU is present then
RingBaseShift contains the offset from the host address.

Suggested-by: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
2017-08-25 10:42:19 +02:00
Brijesh Singh 53a4c6047f OvmfPkg/Virtio: take RingBaseShift in SetQueueAddress()
For the case when an IOMMU is used for translating system physical
addresses to DMA bus master addresses, the transport-independent
virtio device drivers will be required to map their VRING areas to
bus addresses with VIRTIO_DEVICE_PROTOCOL.MapSharedBuffer() calls.

- MMIO and legacy virtio transport do not support IOMMU to translate the
  addresses hence RingBaseShift will always be set to zero.

- modern virtio transport supports IOMMU to translate the address, in
  next patch we will update the Virtio10Dxe to use RingBaseShift offset.

Suggested-by: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
[lersek@redhat.com: remove commit msg paragraph with VirtioLib reference]
[lersek@redhat.com: fix typo in VIRTIO_SET_QUEUE_ADDRESS comment block]
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
2017-08-25 10:42:19 +02:00
Brijesh Singh fc2c1543e5 OvmfPkg/VirtioLib: take VirtIo instance in VirtioRingInit/VirtioRingUninit
Passing the VirtIo protocol instance will allow the vring to use
VIRTIO_DEVICE_PROTOCOL.AllocateSharedPages () to allocate vring buffer.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
2017-08-25 10:42:18 +02:00
Brijesh Singh 0a78d754ed OvmfPkg/VirtioLib: add VirtioMapAllBytesInSharedBuffer() helper function
The function can be used for mapping the system physical address to virtio
device address using VIRTIO_DEVICE_PROTOCOL.MapSharedBuffer (). The
function helps with centralizing error handling, and it allows the caller
to pass in constant or other evaluated expressions for NumberOfBytes.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
[lersek@redhat.com: s/This/VirtIo/ in the new function's comment blocks]
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
2017-08-25 10:42:18 +02:00
Brijesh Singh 084cfc1a35 OvmfPkg/VirtioMmioDeviceLib: implement IOMMU-like member functions
The patch implements the newly added IOMMU-like member functions by
respectively delegating the job to:

- VIRTIO_DEVICE_PROTOCOL.AllocateSharedPages () ->
    MemoryAllocationLib.AllocatePages()

- VIRTIO_DEVICE_PROTOCOL.FreeSharedPages () ->
    MemoryAllocationLib.FreePages ()

- VIRTIO_DEVICE_PROTOCOL.MapSharedBuffer () -> no-op

- VIRTIO_DEVICE_PROTOCOL.UnmapSharedBuffer () -> no-op

Suggested-by: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
2017-08-25 10:42:18 +02:00
Brijesh Singh 4157b8416a OvmfPkg/VirtioPciDeviceDxe: implement IOMMU-like member functions
The patch implements the newly added IOMMU-like member functions by
respectively delegating the job to:

- VIRTIO_DEVICE_PROTOCOL.AllocateSharedPages () ->
    MemoryAllocationLib.AllocatePages()

- VIRTIO_DEVICE_PROTOCOL.FreeSharedPages () ->
    MemoryAllocationLib.FreePages ()

- VIRTIO_DEVICE_PROTOCOL.MapSharedBuffer () -> no-op

- VIRTIO_DEVICE_PROTOCOL.UnmapSharedBuffer () -> no-op

Suggested-by: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
2017-08-25 10:42:18 +02:00
Brijesh Singh de1c57c5f5 OvmfPkg/Virtio10Dxe: implement IOMMU-like member functions
The patch implements the newly added IOMMU-like member functions by
respectively delegating the job to:

- VIRTIO_DEVICE_PROTOCOL.AllocateSharedPages() ->
    EFI_PCI_IO_PROTOCOL.AllocateBuffer()

- VIRTIO_DEVICE_PROTOCOL.FreeSharedPages() ->
    EFI_PCI_IO_PROTOCOL.FreeBuffer()

- VIRTIO_DEVICE_PROTOCOL.MapSharedBuffer() ->
    EFI_PCI_IO_PROTOCOL.Map()

- VIRTIO_DEVICE_PROTOCOL.UnmapSharedBuffer() ->
    EFI_PCI_IO_PROTOCOL.Unmap()

Suggested-by: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
2017-08-25 10:42:18 +02:00
Brijesh Singh 878115261a OvmfPkg: introduce IOMMU-like member functions to VIRTIO_DEVICE_PROTOCOL
The patch extends VIRTIO_DEVICE_PROTOCOL to provide the following new
member functions:

- AllocateSharedPages : allocate a memory region suitable for sharing
   between guest and hypervisor (e.g ring buffer).

- FreeSharedPages: free the memory allocated using AllocateSharedPages ().

- MapSharedBuffer: map a host address to device address suitable to share
   with device for bus master operations.

- UnmapSharedBuffer: unmap the device address obtained through the
   MapSharedBuffer().

We're free to extend the protocol structure without changing the protocol
GUID, or bumping any protocol version fields (of which we currently have
none), because VIRTIO_DEVICE_PROTOCOL is internal to edk2 by design --
see the disclaimers in "VirtioDevice.h".

The patch implements Laszlo's recommendation [1].

[1] http://mid.mail-archive.com/841bec5f-6f6e-8b1f-25ba-0fd37a915b72@redhat.com

Suggested-by: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
2017-08-25 10:42:18 +02:00
Ard Biesheuvel bfb0ee0adb OvmfPkg/QemuVideoDxe: remove AARCH64/ARM support
Now that we have dropped QemuVideoDxe from all QEMU targeted builds
under ArmVirtPkg, we can revert the ARM specific changes to it.

This partially reverts commits 84a75f70e9 (SVN 16890) and
05a5379458.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2017-08-24 15:36:08 +01:00
Laszlo Ersek ca56256d5e OvmfPkg/build.sh: select the GCC49 toolchain settings for gcc-7.*
When UefiCpuPkg/MpInitLib is built for X64 with gcc-7, using the DEBUG
build target and the GCC5 toolchain settings, a C-language assignment is
miscompiled such that the initial AP startup hangs in CpuMpPei (X64) or
CpuDxe (Ia32X64). See <https://bugzilla.tianocore.org/show_bug.cgi?id=671>
for a detailed analysis of the symptoms, and for mailing list links.

This issue has been reported several times (one example is
<https://bugzilla.tianocore.org/show_bug.cgi?id=657>). Until we (or the
upstream gcc developers) figure out how to dissuade gcc-7 from the
miscompilation, pick the GCC49 toolchain in "build.sh" for gcc-7.*.

Cc: Alex Williamson <alex.williamson@redhat.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2017-08-17 11:30:52 +02:00
Brijesh Singh a136bc3ccf OvmfPkg/Protocol/VirtioDevice: fix comment style
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
[lersek@redhat.com: clarify subject line]
[lersek@redhat.com: adjust the set of comments updated by the patch]
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
2017-08-15 21:56:21 +02:00
Brijesh Singh 22701a3d4d OvmfPkg/VirtioMmioDeviceLib: add missing IN and OUT decoration
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
2017-08-15 21:41:45 +02:00
Brijesh Singh e5251fecb9 OvmfPkg/VirtioPciDeviceDxe: add missing IN and OUT decoration
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
2017-08-15 21:36:44 +02:00
Brijesh Singh 365b943345 OvmfPkg/Virtio10Dxe: supply missing BUS_MASTER attribute
Virtio devices read and write guest RAM (they don't just decode their IO
and/or MMIO BARs), which translates to "bus master".

Suggested-by: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
[lersek@redhat.com: expand commit message body]
[lersek@redhat.com: remove superfluous whitespace in assignment]
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
2017-08-15 21:26:30 +02:00
Brijesh Singh 78ef454b8c OvmfPkg/VirtioPciDeviceDxe: supply missing BUS_MASTER attribute
Virtio devices read and write guest RAM (they don't just decode their IO
and/or MMIO BARs), which translates to "bus master".

Suggested-by: Laszlo Ersek <lersek@redhat.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
[lersek@redhat.com: expand commit message body]
[lersek@redhat.com: fix up line breaking style (original code too)]
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
2017-08-15 21:20:16 +02:00
Laszlo Ersek 9e2a8e9289 OvmfPkg/AcpiPlatformDxe: short-circuit the transfer of an empty S3_CONTEXT
In commit 8057622527 ("OvmfPkg/AcpiPlatformDxe: save fw_cfg boot script
with QemuFwCfgS3Lib", 2017-02-23), we replaced the explicit S3 boot script
manipulation in TransferS3ContextToBootScript() with a call to
QemuFwCfgS3CallWhenBootScriptReady(). (Passing AppendFwCfgBootScript() as
callback.)

QemuFwCfgS3CallWhenBootScriptReady() checks for fw_cfg DMA up-front, and
bails with RETURN_NOT_FOUND if fw_cfg DMA is missing.

(This is justified as the goal of QemuFwCfgS3Lib is to "enable[] driver
modules [...] to produce fw_cfg DMA operations that are to be replayed at
S3 resume time".)

In turn, if QemuFwCfgS3CallWhenBootScriptReady() fails, then
OvmfPkg/AcpiPlatformDxe rolls back any earlier linker/loader script
processing, and falls back to the built-in ACPI tables.

(This is also justified because failure to save WRITE_POINTER commands for
replaying at S3 resume implies failure to process the linker/loader script
comprehensively.)

Calling QemuFwCfgS3CallWhenBootScriptReady() from
TransferS3ContextToBootScript() *unconditionally* is wrong however. For
the case when the linker/loader script contains no WRITE_POINTER commands,
the call perpetuated an earlier side effect, and introduced another one:

(1) On machine types that provide fw_cfg DMA (i.e., 2.5+),
    QemuFwCfgS3CallWhenBootScriptReady() would succeed, and allocate
    workspace for the boot script opcodes in reserved memory. However, no
    opcodes would actually be produced in the AppendFwCfgBootScript()
    callback, due to lack of any WRITE_POINTER commands.

    This waste of reserved memory had been introduced in earlier commit
    df73df138d ("OvmfPkg/AcpiPlatformDxe: replay
    QEMU_LOADER_WRITE_POINTER commands at S3", 2017-02-09).

(2) On machine types that lack fw_cfg DMA (i.e., 2.4 and earlier),
    TransferS3ContextToBootScript() would now fail the linker/loader
    script for no reason.

    (Note that QEMU itself prevents adding devices that depend on
    WRITE_POINTER if the machine type lacks fw_cfg DMA:

    $ qemu-system-x86_64 -M pc-q35-2.4 -device vmgenid

    qemu-system-x86_64: -device vmgenid: vmgenid requires DMA write
    support in fw_cfg, which this machine type does not provide)

Short-circuit an empty S3_CONTEXT in TransferS3ContextToBootScript() by
dropping S3_CONTEXT on the floor. This is compatible with the current
contract of the function as it constitutes a transfer of ownership.

Regression (2) was found and reported by Dhiru Kholia as an OSX guest boot
failure on the "pc-q35-2.4" machine type:

http://mid.mail-archive.com/CANO7a6x6EaWNZ8y=MvLU=w_LjRLXserO3NmsgHvaYE0aUCCWzg@mail.gmail.com

Dhiru bisected the issue to commit 8057622527.

Cc: Dhiru Kholia <dhiru.kholia@gmail.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Fixes: df73df138d
Fixes: 8057622527
Reported-by: Dhiru Kholia <dhiru.kholia@gmail.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Dhiru Kholia <dhiru.kholia@gmail.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2017-08-08 15:10:45 +02:00
Laszlo Ersek 1fceaddb12 OvmfPkg/PlatformPei: support >=1TB high RAM, and discontiguous high RAM
In OVMF we currently get the upper (>=4GB) memory size with the
GetSystemMemorySizeAbove4gb() function.

The GetSystemMemorySizeAbove4gb() function is used in two places:

(1) It is the starting point of the calculations in GetFirstNonAddress().
    GetFirstNonAddress() in turn
    - determines the placement of the 64-bit PCI MMIO aperture,
    - provides input for the GCD memory space map's sizing (see
      AddressWidthInitialization(), and the CPU HOB in
      MiscInitialization()),
    - influences the permanent PEI RAM cap (the DXE core's page tables,
      built in permanent PEI RAM, grow as the RAM to map grows).

(2) In QemuInitializeRam(), GetSystemMemorySizeAbove4gb() determines the
    single memory descriptor HOB that we produce for the upper memory.

Respectively, there are two problems with GetSystemMemorySizeAbove4gb():

(1) It reads a 24-bit count of 64KB RAM chunks from the CMOS, and
    therefore cannot return a larger value than one terabyte.

(2) It cannot express discontiguous high RAM.

Starting with version 1.7.0, QEMU has provided the fw_cfg file called
"etc/e820". Refer to the following QEMU commits:

- 0624c7f916b4 ("e820: pass high memory too.", 2013-10-10),
- 7d67110f2d9a ("pc: add etc/e820 fw_cfg file", 2013-10-18)
- 7db16f2480db ("pc: register e820 entries for ram", 2013-10-10)

Ever since these commits in v1.7.0 -- with the last QEMU release being
v2.9.0, and v2.10.0 under development --, the only two RAM entries added
to this E820 map correspond to the below-4GB RAM range, and the above-4GB
RAM range. And, the above-4GB range exactly matches the CMOS registers in
question; see the use of "pcms->above_4g_mem_size":

  pc_q35_init() | pc_init1()
    pc_memory_init()
      e820_add_entry(0x100000000ULL, pcms->above_4g_mem_size, E820_RAM);
    pc_cmos_init()
      val = pcms->above_4g_mem_size / 65536;
      rtc_set_memory(s, 0x5b, val);
      rtc_set_memory(s, 0x5c, val >> 8);
      rtc_set_memory(s, 0x5d, val >> 16);

Therefore, remedy the above OVMF limitations as follows:

(1) Start off GetFirstNonAddress() by scanning the E820 map for the
    highest exclusive >=4GB RAM address. Fall back to the CMOS if the E820
    map is unavailable. Base all further calculations (such as 64-bit PCI
    MMIO aperture placement, GCD sizing etc) on this value.

    At the moment, the only difference this change makes is that we can
    have more than 1TB above 4GB -- given that the sole "high RAM" entry
    in the E820 map matches the CMOS exactly, modulo the most significant
    bits (see above).

    However, Igor plans to add discontiguous (cold-plugged) high RAM to
    the fw_cfg E820 RAM map later on, and then this scanning will adapt
    automatically.

(2) In QemuInitializeRam(), describe the high RAM regions from the E820
    map one by one with memory HOBs. Fall back to the CMOS only if the
    E820 map is missing.

    Again, right now this change only makes a difference if there is at
    least 1TB high RAM. Later on it will adapt to discontiguous high RAM
    (regardless of its size) automatically.

-*-

Implementation details: introduce the ScanOrAdd64BitE820Ram() function,
which reads the E820 entries from fw_cfg, and finds the highest exclusive
>=4GB RAM address, or produces memory resource descriptor HOBs for RAM
entries that start at or above 4GB. The RAM map is not read in a single
go, because its size can vary, and in PlatformPei we should stay away from
dynamic memory allocation, for the following reasons:

- "Pool" allocations are limited to ~64KB, are served from HOBs, and
  cannot be released ever.

- "Page" allocations are seriously limited before PlatformPei installs the
  permanent PEI RAM. Furthermore, page allocations can only be released in
  DXE, with dedicated code (so the address would have to be passed on with
  a HOB or PCD).

- Raw memory allocation HOBs would require the same freeing in DXE.

Therefore we process each E820 entry as soon as it is read from fw_cfg.

-*-

Considering the impact of high RAM on the DXE core:

A few years ago, installing high RAM as *tested* would cause the DXE core
to inhabit such ranges rather than carving out its home from the permanent
PEI RAM. Fortunately, this was fixed in the following edk2 commit:

  3a05b13106, "MdeModulePkg DxeCore: Take the range in resource HOB for
                PHIT as higher priority", 2015-09-18

which I regression-tested at the time:

  http://mid.mail-archive.com/55FC27B0.4070807@redhat.com

Later on, OVMF was changed to install its high RAM as tested (effectively
"arming" the earlier DXE core change for OVMF), in the following edk2
commit:

  035ce3b37c, "OvmfPkg/PlatformPei: Add memory above 4GB as tested",
                2016-04-21

which I also regression-tested at the time:

  http://mid.mail-archive.com/571E8B90.1020102@redhat.com

Therefore adding more "tested memory" HOBs is safe.

Cc: Jordan Justen <jordan.l.justen@intel.com>
Ref: https://bugzilla.redhat.com/show_bug.cgi?id=1468526
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2017-08-05 03:45:09 +02:00
Brijesh Singh f6c909ae5d OvmfPkg/QemuFwCfgLib: Use BusMasterCommonBuffer to map FW_CFG_DMA_ACCESS
Commit 09719a01b1 (OvmfPkg/QemuFwCfgLib: Implement SEV internal function
for Dxe phase) uses IOMMU protocol to allocate and free FW_CFG_DMA_ACCESS
buffer when SEV is active. During initial commits we made assumption that
IOMMU.AllocateBuffer() will provide PlainTextAddress (i.e C-bit cleared).
This assumption was wrong, the AllocateBuffer() protocol member is not
expected to produce a buffer that is immediatly usable, and client is
required to call Map() uncondtionally with BusMasterCommonBuffer[64] to
get a mapping which is accessable by both host and device.

The patch refactors code a bit and add the support to Map()
FW_CFG_DMA_ACCESS buffer using BusMasterCommonBuffer operation after
allocation and Unamp() before free.

The complete discussion about this and recommendation from Laszlo can be
found here [1]

[1] https://lists.01.org/pipermail/edk2-devel/2017-July/012652.html

Suggested-by: Laszlo Ersek <lersek@redhat.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
[lersek@redhat.com: convert pointers to UINTN before converting to UINT64]
[lersek@redhat.com: fix argument indentation in multi-line function call]
[lersek@redhat.com: explicitly compare pointers to NULL]
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Regression-tested-by: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
2017-08-05 02:54:33 +02:00
Laszlo Ersek d0c9afea42 OvmfPkg/IoMmuDxe: Unmap(): recycle MAP_INFO after BusMasterCommonBuffer[64]
In order for Unmap() to be callable from ExitBootServices() event handler
context (for cleaning up a BusMasterCommonBuffer[64] operation), we have
to completely liberate the affected path in Unmap() from dynamic memory
management.

The last remaining piece is the release of the MAP_INFO structure. Rather
than freeing it with FreePool(), recycle it to an internal list. Elements
of this "free list" can be reused for any kind of Map() operation, and can
be freed later, or recycled again.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2017-08-05 01:31:53 +02:00
Laszlo Ersek f1658838c2 OvmfPkg/IoMmuDxe: abort harder on memory encryption mask failures
Upon a MemEncryptSevClearPageEncMask() failure in Map(), it wouldn't be
difficult to release the bounce buffer that was implicitly allocated for
BusMasterRead[64] and BusMasterWrite[64] operations. However, undoing any
partial memory encryption mask changes -- partial page splitting and PTE
modifications -- is practically impossible. (For example, restoring the
encryption mask on the entire range has no reason to fare any better than
the MemEncryptSevClearPageEncMask() call itself.)

For this reason, keep ASSERT_EFI_ERROR(), but hang in RELEASE builds too,
if MemEncryptSevClearPageEncMask() or MemEncryptSevSetPageEncMask() fails.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2017-08-05 01:31:53 +02:00
Laszlo Ersek 58e681406f OvmfPkg/IoMmuDxe: implement in-place decryption/encryption for Map/Unmap
At the moment, we have the following distribution of actions between the
IOMMU protocol member functions:

- AllocateBuffer() allocates pages and clears the memory encryption mask.

- FreeBuffer() re-sets the memory encryption mask, and deallocates pages.

- Map() does nothing at all when BusMasterCommonBuffer[64] is requested
  (and AllocateBuffer() was called previously). Otherwise, Map() allocates
  pages, and clears the memory encryption mask.

- Unmap() does nothing when cleaning up a BusMasterCommonBuffer[64]
  operation. Otherwise, Unmap() clears the encryption mask, and frees the
  pages.

This is wrong: the AllocateBuffer() protocol member is not expected to
produce a buffer that is immediately usable, and client code is required
to call Map() unconditionally, even if BusMasterCommonBuffer[64] is the
desired operation. Implement the right distribution of actions as follows:

- AllocateBuffer() allocates pages and does not touch the encryption mask.

- FreeBuffer() deallocates pages and does not touch the encryption mask.

- Map() does not allocate pages when BusMasterCommonBuffer[64] is
  requested, and it allocates pages (bounce buffer) otherwise.  Regardless
  of the BusMaster operation, Map() (and Map() only) clears the memory
  encryption mask.

- Unmap() restores the encryption mask unconditionally. If the operation
  was BusMasterCommonBuffer[64], then Unmap() does not release the pages.
  Otherwise, the pages (bounce buffer) are released.

This approach also ensures that Unmap() can be called from
ExitBootServices() event handlers, for cleaning up
BusMasterCommonBuffer[64] operations. (More specifically, for restoring
the SEV encryption mask on any in-flight buffers, after resetting any
referring devices.) ExitBootServices() event handlers must not change the
UEFI memory map, thus any memory allocation or freeing in Unmap() would
disqualify Unmap() from being called in such a context.

Map()-ing and Unmap()-ing memory for a BusMasterCommonBuffer[64] operation
effectively means in-place decryption and encryption in a SEV context. As
an additional hurdle, section "7.10.8 Encrypt-in-Place" of AMD publication
Nr.24593 implies that we need a separate temporary buffer for decryption
and encryption that will eventually land in-place. Allocating said
temporary buffer in the straightforward way would violate the above
allocation/freeing restrictions on Map()/Unmap(), therefore pre-allocate
this "stash buffer" too in AllocateBuffer(), and free it in FreeBuffer().

To completely rid Unmap() of dynamic memory impact, for
BusMasterCommonBuffer[64] operations, we're going to rework the lifecycle of
the MAP_INFO structures in a later patch.

(The MemEncryptSevSetPageEncMask() call in Unmap() could theoretically
allocate memory internally for page splitting, however this won't happen
in practice: in Unmap() we only restore the memory encryption mask, and
don't genuinely set it. Any page splitting will have occurred in Map()'s
MemEncryptSevClearPageEncMask() call first.)

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2017-08-05 01:31:53 +02:00
Laszlo Ersek e130229c0a OvmfPkg/IoMmuDxe: rework setup of "MapInfo->PlainTextAddress" in Map()
There are three issues with the current calculations:

- The initial logic that sets up "DmaMemoryTop" and "AllocateType" checks
  for the BusMasterCommonBuffer64 operation in two places. The inner check
  for BusMasterCommonBuffer64 will never evaluate to TRUE however, because
  the outer check excludes BusMasterCommonBuffer64.

- In order to lower "DmaMemoryTop" to (SIZE_4GB - 1), the outer check
  requires that the encrypted (original) buffer cross the 4GB mark. This
  is wrong: for BusMasterRead[64] and BusMasterWrite[64] operations, we
  unconditionally need a bounce buffer (a decrypted memory area), and for
  the 32-bit variants, "DmaMemoryTop" should be lowered regardless of the
  location of the original (encrypted) buffer.

- The current logic would be hard to extend for the in-place decryption
  that we'll implement in the next patch.

Therefore rework the "MapInfo->PlainTextAddress" setup. No functional
changes beyond said bugfixes.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2017-08-05 01:31:53 +02:00
Laszlo Ersek bc1c2e49ac OvmfPkg/IoMmuDxe: zero out pages before releasing them
Whenever we release the plaintext bounce buffer pages that were allocated
implicitly in Map() for BusMasterRead[64] and BusMasterWrite[64], we
restore the encryption mask on them. However, we should also rewrite the
area (fill it with zeros) so that the hypervisor is not left with a
plaintext view of the earlier data.

Similarly, whenever we release the plaintext common buffer pages that were
allocated explicitly in AllocateBuffer() for BusMasterCommonBuffer[64], we
restore the encryption mask on them.  However, we should also rewrite the
area (fill it with zeros) so that the hypervisor is not left with a
plaintext view of the earlier data.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2017-08-05 01:31:53 +02:00
Laszlo Ersek db7ea4d7c4 OvmfPkg/IoMmuDxe: clean up used library classes
The following library classes are not used by this module, so remove them
from the INF file's [LibraryClasses] section:
- DxeServicesTableLib
- UefiLib

The following library classes are used by this module, so add them to the
INF file's [LibraryClasses] section:
- BaseMemoryLib (e.g. via CopyMem())
- MemoryAllocationLib (e.g. via AllocatePool())

Sort the list of library classes (in both "IoMmuDxe.inf" and
"AmdSevIoMmu.h").

Remove all non-local #include directives from "IoMmuDxe.c"; both C files
of this module include "AmdSevIoMmu.h", and "AmdSevIoMmu.h" includes all
non-local headers already.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2017-08-05 01:31:53 +02:00
Laszlo Ersek db1250792c OvmfPkg/IoMmuDxe: propagate errors from AmdSevInstallIoMmuProtocol()
If we cannot install the IOMMU protocol for whatever reason, exit the
driver with an error. The same is already done for the IOMMU Absent
protocol.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2017-08-05 01:31:52 +02:00
Laszlo Ersek 5e365a97ec OvmfPkg/IoMmuDxe: don't initialize local variables
The edk2 coding style requires separate assignments.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2017-08-05 01:31:52 +02:00
Laszlo Ersek 60aa3a0e73 OvmfPkg/IoMmuDxe: convert UINTN arguments to UINT64 for the %Lx fmt spec
The portable way to print UINTN values is to use the %Lx format specifier,
and to convert the values to UINT64. The second step is currently missing,
add it.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2017-08-05 01:31:52 +02:00
Laszlo Ersek c7ef2ed274 OvmfPkg/IoMmuDxe: rename HostAddress to CryptedAddress in MAP_INFO
As a continuation of the last patch, clarify that the area pointed-to by
"HostAddress" is encrypted and hidden from the hypervisor.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2017-08-05 01:31:52 +02:00
Laszlo Ersek dc194ce36d OvmfPkg/IoMmuDxe: rename DeviceAddress to PlainTextAddress in MAP_INFO
In this particular IOMMU driver, "DeviceAddress" is just as accessible to
the CPU as "HostAddress", the difference is that the area pointed-to by
the former is plain-text and accessible to the hypervisor. Rename
"DeviceAddress" to "PlainTextAddress" in MAP_INFO.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Suggested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2017-08-05 01:31:52 +02:00
Laszlo Ersek 812568fb87 OvmfPkg/IoMmuDxe: rewrap source code to 79 characters
No functional changes.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Tested-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Brijesh Singh <brijesh.singh@amd.com>
2017-08-05 01:31:52 +02:00
Thomas Palmer 8dccfa6d48 OvmfPkg/IoMmuDxe: Fix header guard macro
Correct the header guard macro

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Thomas Palmer <thomas.palmer@hpe.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2017-08-05 01:20:01 +02:00
Michael D Kinney 09cc872d02 OvmfPkg: Undo removal of License.txt
Undo removal of OvmfPkg/License.txt in commit

2a98de0344

Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Andrew Fish <afish@apple.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
2017-08-03 11:44:31 -07:00
Michael D Kinney 2a98de0344 edk2: Move License.txt file to root
https://bugzilla.tianocore.org/show_bug.cgi?id=642

Add top level License.txt file with the BSD 2-Clause
License that is used by the majority of the EKD II open
source project content.  Merge copyright statements
from the BSD 2-Clause License files in each package
directory and remove the duplication License.txt
file from package directories.

Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Andrew Fish <afish@apple.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
2017-08-03 11:02:17 -07:00
Michael D Kinney bbdd3bad1b edk2: Move TianoCore Contribution Agreement to root
https://bugzilla.tianocore.org/show_bug.cgi?id=629

Move Contributions.txt that contains the TianoCore
Contribution Agreement 1.0 to the root of the edk2
repository and remove the duplicate Contributions.txt
files from all packages.

Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Andrew Fish <afish@apple.com>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
2017-08-03 11:01:53 -07:00
Brijesh Singh e508e069a8 OvmfPkg/QemuFwCfgLib: Suppress GCC49 IA32 build failure
NumPages variable was introduced in commit 66c548be50. In this commit
we allocate an intermediate buffer when SEV is enabled. The 'BounceBuffer'
variable points to the intermediate buffer pointer and NumPages variables
stores the number of pages. Later in the code, 'BounceBuffer' variable is
checked to see if we need to free the intermediate buffers. The code looks
correct, suppress the warning.

Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Reported-by: Gerd Hoffmann <kraxel@redhat.com>
Reported-by: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
[lersek@redhat.com: s/warnigns/warnings/ in the code comment]
[lersek@redhat.com: add Gerd's Reported-by]
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
2017-07-12 00:16:41 +02:00
Brijesh Singh c6ab9aecb7 OvmfPkg: update PciHostBridgeDxe to use PlatformHasIoMmuLib
This patch enables PciHostBridgeDxe driver to use Platform IoMMU detection
library to ensure that PciHostBridgeDxe is run after platform IoMmuDxe
driver has checked whether platform need to install IOMMU protocol provider.

Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Suggested-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2017-07-10 21:17:28 -07:00
Brijesh Singh 66c548be50 OvmfPkg/QemuFwCfgLib: Add SEV support
When SEV is enabled, use a bounce buffer to perform the DMA operation.

Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2017-07-10 21:17:28 -07:00
Brijesh Singh 7cfe445d7f OvmfPkg/QemuFwCfgLib: Add option to dynamic alloc FW_CFG_DMA Access
Update InternalQemuFwCfgDmaBytes() to work with DMA Access pointer.
The change provides the flexibility to dynamically allocate the "Access"
when SEV is enabled.

Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2017-07-10 21:17:28 -07:00
Brijesh Singh 09719a01b1 OvmfPkg/QemuFwCfgLib: Implement SEV internal function for Dxe phase
When SEV is enabled, the DMA must be performed on unencrypted pages.
So when get asked to perfom FWCFG DMA read or write, we allocate a
intermediate (bounce buffer) unencrypted buffer and use this buffer
for DMA read or write.

Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2017-07-10 21:17:28 -07:00
Brijesh Singh 5feae25392 OvmfPkg/QemuFwCfgLib: Implement SEV internal functions for PEI phase
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2017-07-10 21:17:28 -07:00
Brijesh Singh 6264abc29e OvmfPkg/QemuFwCfgLib: Implement SEV internal function for SEC phase
Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2017-07-10 21:17:28 -07:00
Brijesh Singh b049655d8a OvmfPkg/QemuFwCfgLib: Prepare for SEV support
Add SEV specific internal functions which will be used while intergrating
the SEV support into QemuFwCfgLib.

Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2017-07-10 21:17:28 -07:00
Brijesh Singh fee47a261c OvmfPkg/QemuFwCfgLib: Provide Pei and Dxe specific library
Current QemuFwCfgLib.inf is used in both Pei and Dxe phases. Add Pei
and Dxe inf file to provide a seperate QemuFwCfgLib instances for Pei
and Dxe phases.

Cc: Jordan Justen <jordan.l.justen@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2017-07-10 21:17:28 -07:00