Browse Source

[pcbios] Guard against register corruption in INT 15,e820 implementations

Someone at Dell must have a full-time job designing ways to screw up
implementations of INT 15,e820.  This latest gem is courtesy of a Dell
Xanadu system, which arbitrarily decides to obliterate the contents of
%esi.

Preserve %esi, %edi and %ebp across calls to INT 15,e820, in case
someone tries a variation on this trick in future.
tags/v0.9.6
Michael Brown 16 years ago
parent
commit
bcc70d6b99

+ 6
- 2
src/arch/i386/firmware/pcbios/e820mangler.S View File

268
 	pushl	%ebx
268
 	pushl	%ebx
269
 	pushl	%ecx
269
 	pushl	%ecx
270
 	pushl	%edx
270
 	pushl	%edx
271
+	pushl	%esi	/* Some implementations corrupt %esi, so we	*/
272
+	pushl	%edi	/* preserve %esi, %edi and %ebp to be paranoid	*/
273
+	pushl	%ebp
271
 	pushw	%es
274
 	pushw	%es
272
-	pushw	%di
273
 	pushw	%ds
275
 	pushw	%ds
274
 	popw	%es
276
 	popw	%es
275
 	movw	$underlying_e820_cache, %di
277
 	movw	$underlying_e820_cache, %di
280
 	stc
282
 	stc
281
 	pushfw
283
 	pushfw
282
 	lcall	*%cs:int15_vector
284
 	lcall	*%cs:int15_vector
283
-	popw	%di
284
 	popw	%es
285
 	popw	%es
286
+	popl	%ebp
287
+	popl	%edi
288
+	popl	%esi
285
 	/* Check for error return from underlying e820 call */
289
 	/* Check for error return from underlying e820 call */
286
 	jc	2f /* CF set: error */
290
 	jc	2f /* CF set: error */
287
 	cmpl	$SMAP, %eax
291
 	cmpl	$SMAP, %eax

+ 5
- 1
src/arch/i386/firmware/pcbios/memmap.c View File

167
 	memset ( &e820buf, 0, sizeof ( e820buf ) );
167
 	memset ( &e820buf, 0, sizeof ( e820buf ) );
168
 
168
 
169
 	do {
169
 	do {
170
+		/* Some BIOSes corrupt %esi for fun. Guard against
171
+		 * this by telling gcc that all non-output registers
172
+		 * may be corrupted.
173
+		 */
170
 		__asm__ __volatile__ ( REAL_CODE ( "stc\n\t"
174
 		__asm__ __volatile__ ( REAL_CODE ( "stc\n\t"
171
 						   "int $0x15\n\t"
175
 						   "int $0x15\n\t"
172
 						   "pushfw\n\t"
176
 						   "pushfw\n\t"
178
 					 "D" ( __from_data16 ( &e820buf ) ),
182
 					 "D" ( __from_data16 ( &e820buf ) ),
179
 					 "c" ( sizeof ( e820buf ) ),
183
 					 "c" ( sizeof ( e820buf ) ),
180
 					 "d" ( SMAP )
184
 					 "d" ( SMAP )
181
-				       : "memory" );
185
+				       : "esi", "memory" );
182
 
186
 
183
 		if ( smap != SMAP ) {
187
 		if ( smap != SMAP ) {
184
 			DBG ( "INT 15,e820 failed SMAP signature check\n" );
188
 			DBG ( "INT 15,e820 failed SMAP signature check\n" );

Loading…
Cancel
Save