Browse Source

[efi] Raise TPL within EFI_DRIVER_BINDING_PROTOCOL entry points

Debugged-by: Rob Taglang <rob@privatemachines.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 6 years ago
parent
commit
10d083ffa9
1 changed files with 19 additions and 0 deletions
  1. 19
    0
      src/interface/efi/efi_driver.c

+ 19
- 0
src/interface/efi/efi_driver.c View File

@@ -95,7 +95,9 @@ struct efi_device * efidev_parent ( struct device *dev ) {
95 95
 static EFI_STATUS EFIAPI
96 96
 efi_driver_supported ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
97 97
 		       EFI_HANDLE device, EFI_DEVICE_PATH_PROTOCOL *child ) {
98
+	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
98 99
 	struct efi_driver *efidrv;
100
+	EFI_TPL saved_tpl;
99 101
 	int rc;
100 102
 
101 103
 	DBGCP ( device, "EFIDRV %s DRIVER_SUPPORTED",
@@ -111,17 +113,22 @@ efi_driver_supported ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
111 113
 		return EFI_ALREADY_STARTED;
112 114
 	}
113 115
 
116
+	/* Raise TPL */
117
+	saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
118
+
114 119
 	/* Look for a driver claiming to support this device */
115 120
 	for_each_table_entry ( efidrv, EFI_DRIVERS ) {
116 121
 		if ( ( rc = efidrv->supported ( device ) ) == 0 ) {
117 122
 			DBGC ( device, "EFIDRV %s has driver \"%s\"\n",
118 123
 			       efi_handle_name ( device ), efidrv->name );
124
+			bs->RestoreTPL ( saved_tpl );
119 125
 			return 0;
120 126
 		}
121 127
 	}
122 128
 	DBGCP ( device, "EFIDRV %s has no driver\n",
123 129
 		efi_handle_name ( device ) );
124 130
 
131
+	bs->RestoreTPL ( saved_tpl );
125 132
 	return EFI_UNSUPPORTED;
126 133
 }
127 134
 
@@ -145,6 +152,7 @@ efi_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
145 152
 	} path;
146 153
 	EFI_DEVICE_PATH_PROTOCOL *path_end;
147 154
 	size_t path_len;
155
+	EFI_TPL saved_tpl;
148 156
 	EFI_STATUS efirc;
149 157
 	int rc;
150 158
 
@@ -162,6 +170,9 @@ efi_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
162 170
 		goto err_already_started;
163 171
 	}
164 172
 
173
+	/* Raise TPL */
174
+	saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
175
+
165 176
 	/* Do nothing if we are currently disconnecting drivers */
166 177
 	if ( efi_driver_disconnecting ) {
167 178
 		DBGC ( device, "EFIDRV %s refusing to start during "
@@ -215,6 +226,7 @@ efi_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
215 226
 			DBGC ( device, "EFIDRV %s using driver \"%s\"\n",
216 227
 			       efi_handle_name ( device ),
217 228
 			       efidev->driver->name );
229
+			bs->RestoreTPL ( saved_tpl );
218 230
 			return 0;
219 231
 		}
220 232
 		DBGC ( device, "EFIDRV %s could not start driver \"%s\": %s\n",
@@ -232,6 +244,7 @@ efi_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
232 244
 	}
233 245
  err_open_path:
234 246
  err_disconnecting:
247
+	bs->RestoreTPL ( saved_tpl );
235 248
  err_already_started:
236 249
 	return efirc;
237 250
 }
@@ -250,8 +263,10 @@ static EFI_STATUS EFIAPI
250 263
 efi_driver_stop ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
251 264
 		  EFI_HANDLE device, UINTN num_children,
252 265
 		  EFI_HANDLE *children ) {
266
+	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
253 267
 	struct efi_driver *efidrv;
254 268
 	struct efi_device *efidev;
269
+	EFI_TPL saved_tpl;
255 270
 	UINTN i;
256 271
 
257 272
 	DBGC ( device, "EFIDRV %s DRIVER_STOP", efi_handle_name ( device ) );
@@ -269,6 +284,9 @@ efi_driver_stop ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
269 284
 		return EFI_DEVICE_ERROR;
270 285
 	}
271 286
 
287
+	/* Raise TPL */
288
+	saved_tpl = bs->RaiseTPL ( TPL_CALLBACK );
289
+
272 290
 	/* Stop this device */
273 291
 	efidrv = efidev->driver;
274 292
 	assert ( efidrv != NULL );
@@ -276,6 +294,7 @@ efi_driver_stop ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
276 294
 	list_del ( &efidev->dev.siblings );
277 295
 	free ( efidev );
278 296
 
297
+	bs->RestoreTPL ( saved_tpl );
279 298
 	return 0;
280 299
 }
281 300
 

Loading…
Cancel
Save