cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

BiosTablesTest.c (4942B)


      1/** @file
      2  Populate the BIOS_TABLES_TEST structure.
      3
      4  Copyright (C) 2019, Red Hat, Inc.
      5
      6  This program and the accompanying materials are licensed and made available
      7  under the terms and conditions of the BSD License that accompanies this
      8  distribution. The full text of the license may be found at
      9  <http://opensource.org/licenses/bsd-license.php>.
     10
     11  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
     12  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     13**/
     14
     15#include <Guid/Acpi.h>
     16#include <Guid/BiosTablesTest.h>
     17#include <Guid/SmBios.h>
     18#include <Library/BaseLib.h>
     19#include <Library/BaseMemoryLib.h>
     20#include <Library/MemoryAllocationLib.h>
     21#include <Library/UefiBootServicesTableLib.h>
     22#include <Library/UefiLib.h>
     23
     24/**
     25  Wait for a keypress with a message that the application is about to exit.
     26**/
     27STATIC
     28VOID
     29WaitForExitKeyPress (
     30  VOID
     31  )
     32{
     33  EFI_STATUS    Status;
     34  UINTN         Idx;
     35  EFI_INPUT_KEY Key;
     36
     37  if (gST->ConIn == NULL) {
     38    return;
     39  }
     40  AsciiPrint ("%a: press any key to exit\n", gEfiCallerBaseName);
     41  Status = gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &Idx);
     42  if (EFI_ERROR (Status)) {
     43    return;
     44  }
     45  gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
     46}
     47
     48EFI_STATUS
     49EFIAPI
     50BiosTablesTestMain (
     51  IN EFI_HANDLE       ImageHandle,
     52  IN EFI_SYSTEM_TABLE *SystemTable
     53  )
     54{
     55  VOID                          *Pages;
     56  volatile BIOS_TABLES_TEST     *BiosTablesTest;
     57  CONST VOID                    *Rsdp10;
     58  CONST VOID                    *Rsdp20;
     59  CONST VOID                    *Smbios21;
     60  CONST VOID                    *Smbios30;
     61  CONST EFI_CONFIGURATION_TABLE *ConfigTable;
     62  CONST EFI_CONFIGURATION_TABLE *ConfigTablesEnd;
     63  volatile EFI_GUID             *InverseSignature;
     64  UINTN                         Idx;
     65
     66  Pages = AllocateAlignedPages (EFI_SIZE_TO_PAGES (sizeof *BiosTablesTest),
     67            SIZE_1MB);
     68  if (Pages == NULL) {
     69    AsciiErrorPrint ("%a: AllocateAlignedPages() failed\n",
     70      gEfiCallerBaseName);
     71    //
     72    // Assuming the application was launched by the boot manager as a boot
     73    // loader, exiting with error will cause the boot manager to proceed with
     74    // the remaining boot options. If there are no other boot options, the boot
     75    // manager menu will be pulled up. Give the user a chance to read the error
     76    // message.
     77    //
     78    WaitForExitKeyPress ();
     79    return EFI_OUT_OF_RESOURCES;
     80  }
     81
     82  //
     83  // Locate all the gEfiAcpi10TableGuid, gEfiAcpi20TableGuid,
     84  // gEfiSmbiosTableGuid, gEfiSmbios3TableGuid config tables in one go.
     85  //
     86  Rsdp10 = NULL;
     87  Rsdp20 = NULL;
     88  Smbios21 = NULL;
     89  Smbios30 = NULL;
     90  ConfigTable = gST->ConfigurationTable;
     91  ConfigTablesEnd = gST->ConfigurationTable + gST->NumberOfTableEntries;
     92  while ((Rsdp10 == NULL || Rsdp20 == NULL ||
     93          Smbios21 == NULL || Smbios30 == NULL) &&
     94         ConfigTable < ConfigTablesEnd) {
     95    if (CompareGuid (&ConfigTable->VendorGuid, &gEfiAcpi10TableGuid)) {
     96      Rsdp10 = ConfigTable->VendorTable;
     97    } else if (CompareGuid (&ConfigTable->VendorGuid, &gEfiAcpi20TableGuid)) {
     98      Rsdp20 = ConfigTable->VendorTable;
     99    } else if (CompareGuid (&ConfigTable->VendorGuid, &gEfiSmbiosTableGuid)) {
    100      Smbios21 = ConfigTable->VendorTable;
    101    } else if (CompareGuid (&ConfigTable->VendorGuid, &gEfiSmbios3TableGuid)) {
    102      Smbios30 = ConfigTable->VendorTable;
    103    }
    104    ++ConfigTable;
    105  }
    106
    107  AsciiPrint ("%a: BiosTablesTest=%p Rsdp10=%p Rsdp20=%p\n",
    108    gEfiCallerBaseName, Pages, Rsdp10, Rsdp20);
    109  AsciiPrint ("%a: Smbios21=%p Smbios30=%p\n", gEfiCallerBaseName, Smbios21,
    110    Smbios30);
    111
    112  //
    113  // Store the config table addresses first, then the signature second.
    114  //
    115  BiosTablesTest = Pages;
    116  BiosTablesTest->Rsdp10 = (UINTN)Rsdp10;
    117  BiosTablesTest->Rsdp20 = (UINTN)Rsdp20;
    118  BiosTablesTest->Smbios21 = (UINTN)Smbios21;
    119  BiosTablesTest->Smbios30 = (UINTN)Smbios30;
    120
    121  MemoryFence();
    122
    123  InverseSignature = &BiosTablesTest->InverseSignatureGuid;
    124  InverseSignature->Data1  = gBiosTablesTestGuid.Data1;
    125  InverseSignature->Data1 ^= MAX_UINT32;
    126  InverseSignature->Data2  = gBiosTablesTestGuid.Data2;
    127  InverseSignature->Data2 ^= MAX_UINT16;
    128  InverseSignature->Data3  = gBiosTablesTestGuid.Data3;
    129  InverseSignature->Data3 ^= MAX_UINT16;
    130  for (Idx = 0; Idx < sizeof InverseSignature->Data4; ++Idx) {
    131    InverseSignature->Data4[Idx]  = gBiosTablesTestGuid.Data4[Idx];
    132    InverseSignature->Data4[Idx] ^= MAX_UINT8;
    133  }
    134
    135  //
    136  // The wait below has dual purpose. First, it blocks the application without
    137  // wasting VCPU cycles while the hypervisor is scanning guest RAM. Second,
    138  // assuming the application was launched by the boot manager as a boot
    139  // loader, exiting the app with success causes the boot manager to pull up
    140  // the boot manager menu at once (regardless of other boot options); the wait
    141  // gives the user a chance to read the info printed above.
    142  //
    143  WaitForExitKeyPress ();
    144  return EFI_SUCCESS;
    145}