@@ -44,6 +44,23 @@ 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 , buffer_properties_t * bprop )
50+ {
51+ EFI_STATUS status ;
52+
53+ status = validate_cached_section (parent_image_handle ,
54+ bprop -> buffer , bprop -> size );
55+ if (EFI_ERROR (status ))
56+ return status ;
57+
58+ bprop -> allocated_buffer = false;
59+ bprop -> dp = dp ;
60+
61+ return EFI_SUCCESS ;
62+ }
63+
4764static EFI_STATUS
4865try_load_from_sfs (EFI_DEVICE_PATH * dp , buffer_properties_t * bprop )
4966{
@@ -179,37 +196,60 @@ shim_load_image(BOOLEAN BootPolicy, EFI_HANDLE ParentImageHandle,
179196 if (BootPolicy )
180197 return EFI_UNSUPPORTED ;
181198
182- if (!SourceBuffer || !SourceSize ) {
183- if (!DevicePath ) /* Both SourceBuffer and DevicePath are NULL */
184- return EFI_NOT_FOUND ;
185-
186- if (try_load_from_sfs (DevicePath , & bprop ) == EFI_SUCCESS )
187- ;
188- else if (try_load_from_lf2 (DevicePath , & bprop ) == EFI_SUCCESS )
189- ;
190- else
191- /* no buffer given and we cannot load from this device */
199+ /*
200+ * First we're checking if it's cached - since that is quite fast
201+ * unless we have a match, and any match is okay, we don't need to
202+ * do anything more complicated.
203+ */
204+ if (SourceSize && SourceBuffer ) {
205+ bprop .buffer = SourceBuffer ;
206+ bprop .size = SourceSize ;
207+ efi_status = try_load_from_cached_section (ParentImageHandle ,
208+ DevicePath , & bprop );
209+ if (!EFI_ERROR (efi_status )) {
210+ parent_verified = true;
211+ } else if (efi_status != EFI_NOT_FOUND ) {
192212 return EFI_LOAD_ERROR ;
213+ }
214+ }
193215
194- SourceBuffer = bprop .buffer ;
195- SourceSize = bprop .size ;
196- } else {
197- bprop .buffer = NULL ;
198- /*
199- * Even if we are using a buffer, try populating the
200- * device_handle and file_path fields the best we can
201- */
202-
203- bprop .dp = DevicePath ;
204-
205- if (bprop .dp ) {
206- efi_status = BS -> LocateDevicePath (& gEfiDevicePathProtocolGuid ,
207- & bprop .dp ,
208- & bprop .hnd );
209- if (efi_status != EFI_SUCCESS ) {
210- /* can't seem to pull apart this DP */
211- bprop .dp = DevicePath ;
212- bprop .hnd = NULL ;
216+ /*
217+ * If we don't already have a cached, verified copy of the object
218+ * being loaded, go about it the old way.
219+ */
220+ if (!parent_verified ) {
221+ if (!SourceBuffer || !SourceSize ) {
222+ if (!DevicePath ) /* Both SourceBuffer and DevicePath are NULL */
223+ return EFI_NOT_FOUND ;
224+
225+ if (try_load_from_sfs (DevicePath , & bprop ) == EFI_SUCCESS )
226+ ;
227+ else if (try_load_from_lf2 (DevicePath , & bprop ) == EFI_SUCCESS )
228+ ;
229+ else
230+ /* no buffer given and we cannot load from this device */
231+ return EFI_LOAD_ERROR ;
232+
233+ SourceBuffer = bprop .buffer ;
234+ SourceSize = bprop .size ;
235+ } else {
236+ bprop .buffer = NULL ;
237+ /*
238+ * Even if we are using a buffer, try populating the
239+ * device_handle and file_path fields the best we can
240+ */
241+
242+ bprop .dp = DevicePath ;
243+
244+ if (bprop .dp ) {
245+ efi_status = BS -> LocateDevicePath (& gEfiDevicePathProtocolGuid ,
246+ & bprop .dp ,
247+ & bprop .hnd );
248+ if (efi_status != EFI_SUCCESS ) {
249+ /* can't seem to pull apart this DP */
250+ bprop .dp = DevicePath ;
251+ bprop .hnd = NULL ;
252+ }
213253 }
214254 }
215255 }
0 commit comments