Bladeren bron

OvmfPkg/PlatformDxe: Handle all requests in ExtractConfig and RouteConfig

Per the UEFI specification, if the Request argument in
EFI_HII_CONFIG_ACCESS_PROTOCOL.ExtractConfig() is NULL or does not contain
any request elements, the implementation should return all of the settings
being abstracted for the particular ConfigHdr reference.

The current implementation returns EFI_INVALID_PARAMETER if Request is
NULL or does not contain any request elements. Instead, construct
a new ConfigRequest to handle these cases per the specification.

In addition, per the UEFI specification, if the Configuration argument in
EFI_HII_CONFIG_ACCESS_PROTOCOL.RouteConfig() has a ConfigHdr that
specifies a non-existing target, the implementation should return
EFI_NOT_FOUND.

The current implementation returns EFI_INVALID_PARAMETER if Configuration
has a non-existing target in ConfigHdr. Instead, perform a check and
return EFI_NOT_FOUND in this case.

Signed-off-by: Dimitrije Pavlov <Dimitrije.Pavlov@arm.com>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Dimitrije Pavlov 1 jaar geleden
bovenliggende
commit
aefcc91805
3 gewijzigde bestanden met toevoegingen van 116 en 3 verwijderingen
  1. 113 2
      OvmfPkg/PlatformDxe/Platform.c
  2. 1 1
      OvmfPkg/PlatformDxe/PlatformConfig.c
  3. 2 0
      OvmfPkg/PlatformDxe/PlatformConfig.h

+ 113 - 2
OvmfPkg/PlatformDxe/Platform.c

@@ -108,6 +108,11 @@ STATIC EFI_EVENT  mGopEvent;
 //
 STATIC VOID  *mGopTracker;
 
+//
+// The driver image handle, used to obtain the device path for <ConfigHdr>.
+//
+STATIC EFI_HANDLE  mImageHandle;
+
 //
 // Cache the resolutions we get from the GOP.
 //
@@ -229,6 +234,10 @@ ExtractConfig (
 {
   MAIN_FORM_STATE  MainFormState;
   EFI_STATUS       Status;
+  EFI_STRING       ConfigRequestHdr;
+  EFI_STRING       ConfigRequest;
+  UINTN            Size;
+  BOOLEAN          AllocatedRequest;
 
   DEBUG ((DEBUG_VERBOSE, "%a: Request=\"%s\"\n", __FUNCTION__, Request));
 
@@ -236,18 +245,73 @@ ExtractConfig (
     return EFI_INVALID_PARAMETER;
   }
 
+  ConfigRequestHdr = NULL;
+  ConfigRequest    = NULL;
+  Size             = 0;
+  AllocatedRequest = FALSE;
+
+  //
+  // Check if <ConfigHdr> matches the GUID and name
+  //
+  *Progress = Request;
+  if ((Request != NULL) &&
+      !HiiIsConfigHdrMatch (
+         Request,
+         &gOvmfPlatformConfigGuid,
+         mVariableName
+         )
+      )
+  {
+    return EFI_NOT_FOUND;
+  }
+
   Status = PlatformConfigToFormState (&MainFormState);
   if (EFI_ERROR (Status)) {
-    *Progress = Request;
     return Status;
   }
 
+  if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
+    //
+    // Request has no <RequestElement>, so construct full request string.
+    // Allocate and fill a buffer large enough to hold <ConfigHdr>
+    // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a
+    // null terminator.
+    //
+    ConfigRequestHdr = HiiConstructConfigHdr (
+                         &gOvmfPlatformConfigGuid,
+                         mVariableName,
+                         mImageHandle
+                         );
+    if (ConfigRequestHdr == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+
+    Size             = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
+    ConfigRequest    = AllocateZeroPool (Size);
+    AllocatedRequest = TRUE;
+    if (ConfigRequest == NULL) {
+      FreePool (ConfigRequestHdr);
+      return EFI_OUT_OF_RESOURCES;
+    }
+
+    UnicodeSPrint (
+      ConfigRequest,
+      Size,
+      L"%s&OFFSET=0&WIDTH=%016LX",
+      ConfigRequestHdr,
+      sizeof MainFormState
+      );
+    FreePool (ConfigRequestHdr);
+  } else {
+    ConfigRequest = Request;
+  }
+
   //
   // Answer the textual request keying off the binary form state.
   //
   Status = gHiiConfigRouting->BlockToConfig (
                                 gHiiConfigRouting,
-                                Request,
+                                ConfigRequest,
                                 (VOID *)&MainFormState,
                                 sizeof MainFormState,
                                 Results,
@@ -265,6 +329,33 @@ ExtractConfig (
     DEBUG ((DEBUG_VERBOSE, "%a: Results=\"%s\"\n", __FUNCTION__, *Results));
   }
 
+  //
+  // If we used a newly allocated ConfigRequest, update Progress to point to
+  // original Request instead of ConfigRequest.
+  //
+  if (Request == NULL) {
+    *Progress = NULL;
+  } else if (StrStr (Request, L"OFFSET") == NULL) {
+    if (EFI_ERROR (Status)) {
+      //
+      // Since we constructed ConfigRequest, failure can only occur if there
+      // is not enough memory. In this case, we point Progress to the first
+      // character of Request.
+      //
+      *Progress = Request;
+    } else {
+      //
+      // In case of success, we point Progress to the null terminator of
+      // Request.
+      //
+      *Progress = Request + StrLen (Request);
+    }
+  }
+
+  if (AllocatedRequest) {
+    FreePool (ConfigRequest);
+  }
+
   return Status;
 }
 
@@ -348,6 +439,21 @@ RouteConfig (
     return EFI_INVALID_PARAMETER;
   }
 
+  //
+  // Check if <ConfigHdr> matches the GUID and name
+  //
+  *Progress = Configuration;
+  if ((Configuration != NULL) &&
+      !HiiIsConfigHdrMatch (
+         Configuration,
+         &gOvmfPlatformConfigGuid,
+         mVariableName
+         )
+      )
+  {
+    return EFI_NOT_FOUND;
+  }
+
   //
   // the "read" step in RMW
   //
@@ -866,6 +972,11 @@ PlatformInit (
     return Status;
   }
 
+  //
+  // Save the driver image handle.
+  //
+  mImageHandle = ImageHandle;
+
   //
   // Publish the HII package list to HII Database.
   //

+ 1 - 1
OvmfPkg/PlatformDxe/PlatformConfig.c

@@ -21,7 +21,7 @@
 //
 // Name of the UEFI variable that we use for persistent storage.
 //
-STATIC CHAR16  mVariableName[] = L"PlatformConfig";
+CHAR16  mVariableName[] = L"PlatformConfig";
 
 /**
   Serialize and persistently save platform configuration.

+ 2 - 0
OvmfPkg/PlatformDxe/PlatformConfig.h

@@ -50,4 +50,6 @@ PlatformConfigLoad (
 #define PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION  BIT0
 #define PLATFORM_CONFIG_F_DOWNGRADE            BIT63
 
+extern CHAR16  mVariableName[];
+
 #endif // _PLATFORM_CONFIG_H_