@@ -44,6 +44,24 @@ typedef struct {
4444 bool allocated_buffer ;
4545} buffer_properties_t ;
4646
47+ static EFI_STATUS
48+ try_load_from_cached_section (EFI_HANDLE parent_image_handle ,
49+ EFI_DEVICE_PATH * dp ,
50+ buffer_properties_t * bprop )
51+ {
52+ EFI_STATUS status ;
53+
54+ status = validate_cached_section (parent_image_handle ,
55+ bprop -> buffer , bprop -> size );
56+ if (EFI_ERROR (status ))
57+ return status ;
58+
59+ bprop -> allocated_buffer = false;
60+ bprop -> dp = dp ;
61+
62+ return EFI_SUCCESS ;
63+ }
64+
4765static EFI_STATUS
4866try_load_from_sfs (EFI_DEVICE_PATH * dp , buffer_properties_t * bprop )
4967{
@@ -183,37 +201,60 @@ shim_load_image(BOOLEAN BootPolicy, EFI_HANDLE ParentImageHandle,
183201 if (BootPolicy )
184202 return EFI_UNSUPPORTED ;
185203
186- if (!SourceBuffer || !SourceSize ) {
187- if (!DevicePath ) /* Both SourceBuffer and DevicePath are NULL */
188- return EFI_NOT_FOUND ;
189-
190- if (try_load_from_sfs (DevicePath , & bprop ) == EFI_SUCCESS )
191- ;
192- else if (try_load_from_lf2 (DevicePath , & bprop ) == EFI_SUCCESS )
193- ;
194- else
195- /* no buffer given and we cannot load from this device */
204+ /*
205+ * First we're checking if it's cached - since that is quite fast
206+ * unless we have a match, and any match is okay, we don't need to
207+ * do anything more complicated.
208+ */
209+ if (SourceSize && SourceBuffer ) {
210+ bprop .buffer = SourceBuffer ;
211+ bprop .size = SourceSize ;
212+ efi_status = try_load_from_cached_section (ParentImageHandle ,
213+ DevicePath , & bprop );
214+ if (!EFI_ERROR (efi_status )) {
215+ parent_verified = true;
216+ } else if (efi_status != EFI_NOT_FOUND ) {
196217 return EFI_LOAD_ERROR ;
218+ }
219+ }
197220
198- SourceBuffer = bprop .buffer ;
199- SourceSize = bprop .size ;
200- } else {
201- bprop .buffer = NULL ;
202- /*
203- * Even if we are using a buffer, try populating the
204- * device_handle and file_path fields the best we can
205- */
206-
207- bprop .dp = DevicePath ;
208-
209- if (bprop .dp ) {
210- efi_status = BS -> LocateDevicePath (& gEfiDevicePathProtocolGuid ,
211- & bprop .dp ,
212- & bprop .hnd );
213- if (efi_status != EFI_SUCCESS ) {
214- /* can't seem to pull apart this DP */
215- bprop .dp = DevicePath ;
216- bprop .hnd = NULL ;
221+ /*
222+ * If we don't already have a cached, verified copy of the object
223+ * being loaded, go about it the old way.
224+ */
225+ if (!parent_verified ) {
226+ if (!SourceBuffer || !SourceSize ) {
227+ if (!DevicePath ) /* Both SourceBuffer and DevicePath are NULL */
228+ return EFI_NOT_FOUND ;
229+
230+ if (try_load_from_sfs (DevicePath , & bprop ) == EFI_SUCCESS )
231+ ;
232+ else if (try_load_from_lf2 (DevicePath , & bprop ) == EFI_SUCCESS )
233+ ;
234+ else
235+ /* no buffer given and we cannot load from this device */
236+ return EFI_LOAD_ERROR ;
237+
238+ SourceBuffer = bprop .buffer ;
239+ SourceSize = bprop .size ;
240+ } else {
241+ bprop .buffer = NULL ;
242+ /*
243+ * Even if we are using a buffer, try populating the
244+ * device_handle and file_path fields the best we can
245+ */
246+
247+ bprop .dp = DevicePath ;
248+
249+ if (bprop .dp ) {
250+ efi_status = BS -> LocateDevicePath (& gEfiDevicePathProtocolGuid ,
251+ & bprop .dp ,
252+ & bprop .hnd );
253+ if (efi_status != EFI_SUCCESS ) {
254+ /* can't seem to pull apart this DP */
255+ bprop .dp = DevicePath ;
256+ bprop .hnd = NULL ;
257+ }
217258 }
218259 }
219260 }
0 commit comments