Browse Source

[pcbios] Don't use "lret $2" to return from an interrupt

Using "lret $2" to return from an interrupt causes interrupts to be
disabled in the calling program, since the INT instruction will have
disabled interrupts.  Instead, patch CF on the stack and use iret to
return.

Interestingly, the original PC BIOS had this bug in at least one
place.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Michael Brown <mcb30@etherboot.org>
tags/v0.9.8
H. Peter Anvin 15 years ago
parent
commit
f44205b9ea

+ 18
- 9
src/arch/i386/firmware/pcbios/e820mangler.S View File

489
 	ret
489
 	ret
490
 	.size get_mangled_e820, . - get_mangled_e820
490
 	.size get_mangled_e820, . - get_mangled_e820
491
 
491
 
492
+/****************************************************************************
493
+ * Set/clear CF on the stack as appropriate, assumes stack is as it should
494
+ * be immediately before IRET
495
+ ****************************************************************************
496
+ */
497
+patch_cf:
498
+	pushw	%bp
499
+	movw	%sp, %bp
500
+	setc	8(%bp)	/* Set/reset CF; clears PF, AF, ZF, SF */
501
+	popw	%bp
502
+	ret
503
+
492
 /****************************************************************************
504
 /****************************************************************************
493
  * INT 15,e820 handler
505
  * INT 15,e820 handler
494
  ****************************************************************************
506
  ****************************************************************************
500
 	popw	%ds
512
 	popw	%ds
501
 	call	get_mangled_e820
513
 	call	get_mangled_e820
502
 	popw	%ds
514
 	popw	%ds
503
-	lret	$2
515
+	call	patch_cf
516
+	iret
504
 	.size int15_e820, . - int15_e820
517
 	.size int15_e820, . - int15_e820
505
 	
518
 	
506
 /****************************************************************************
519
 /****************************************************************************
512
 	/* Call previous handler */
525
 	/* Call previous handler */
513
 	pushfw
526
 	pushfw
514
 	lcall	*%cs:int15_vector
527
 	lcall	*%cs:int15_vector
515
-	pushfw
528
+	call	patch_cf
516
 	/* Edit result */
529
 	/* Edit result */
517
 	pushw	%ds
530
 	pushw	%ds
518
 	pushw	%cs:rm_ds
531
 	pushw	%cs:rm_ds
524
 	xchgw	%ax, %cx
537
 	xchgw	%ax, %cx
525
 	xchgw	%bx, %dx
538
 	xchgw	%bx, %dx
526
 	popw	%ds
539
 	popw	%ds
527
-	/* Restore flags returned by previous handler and return */
528
-	popfw
529
-	lret	$2
540
+	iret
530
 	.size int15_e801, . - int15_e801
541
 	.size int15_e801, . - int15_e801
531
 	
542
 	
532
 /****************************************************************************
543
 /****************************************************************************
538
 	/* Call previous handler */
549
 	/* Call previous handler */
539
 	pushfw
550
 	pushfw
540
 	lcall	*%cs:int15_vector
551
 	lcall	*%cs:int15_vector
541
-	pushfw
552
+	call	patch_cf
542
 	/* Edit result */
553
 	/* Edit result */
543
 	pushw	%ds
554
 	pushw	%ds
544
 	pushw	%cs:rm_ds
555
 	pushw	%cs:rm_ds
545
 	popw	%ds
556
 	popw	%ds
546
 	call	patch_1m
557
 	call	patch_1m
547
 	popw	%ds
558
 	popw	%ds
548
-	/* Restore flags returned by previous handler and return */
549
-	popfw
550
-	lret	$2
559
+	iret
551
 	.size int15_88, . - int15_88
560
 	.size int15_88, . - int15_88
552
 		
561
 		
553
 /****************************************************************************
562
 /****************************************************************************

+ 3
- 2
src/arch/i386/firmware/pcbios/fakee820.c View File

63
 			      "cmpl $0x534d4150, %%edx\n\t"
63
 			      "cmpl $0x534d4150, %%edx\n\t"
64
 			      "jne 99f\n\t"
64
 			      "jne 99f\n\t"
65
 			      "pushaw\n\t"
65
 			      "pushaw\n\t"
66
+			      "movw %%sp, %%bp\n\t"
67
+			      "andb $~0x01, 22(%%bp)\n\t" /* Clear return CF */
66
 			      "leaw e820map(%%bx), %%si\n\t"
68
 			      "leaw e820map(%%bx), %%si\n\t"
67
 			      "cs rep movsb\n\t"
69
 			      "cs rep movsb\n\t"
68
 			      "popaw\n\t"
70
 			      "popaw\n\t"
73
 			      "xorl %%ebx,%%ebx\n\t"
75
 			      "xorl %%ebx,%%ebx\n\t"
74
 			      "\n1:\n\t"
76
 			      "\n1:\n\t"
75
 			      "popfw\n\t"
77
 			      "popfw\n\t"
76
-			      "clc\n\t"
77
-			      "lret $2\n\t"
78
+			      "iret\n\t"
78
 			      "\n99:\n\t"
79
 			      "\n99:\n\t"
79
 			      "popfw\n\t"
80
 			      "popfw\n\t"
80
 			      "ljmp *%%cs:real_int15_vector\n\t" )
81
 			      "ljmp *%%cs:real_int15_vector\n\t" )

+ 5
- 2
src/arch/i386/interface/pxe/pxe_entry.S View File

199
 	shll	$4, %edx
199
 	shll	$4, %edx
200
 	addl	$pxenv, %edx
200
 	addl	$pxenv, %edx
201
 	movw	$0x564e, %ax
201
 	movw	$0x564e, %ax
202
+	pushw	%bp
203
+	movw	%sp, %bp
204
+	andb	$~0x01, 8(%bp)	/* Clear CF on return */
205
+	popw	%bp
202
 	popfw
206
 	popfw
203
-	clc
204
-	lret	$2
207
+	iret
205
 1:	/* INT 1A,other - pass through */
208
 1:	/* INT 1A,other - pass through */
206
 	popfw
209
 	popfw
207
 	ljmp	*%cs:pxe_int_1a_vector
210
 	ljmp	*%cs:pxe_int_1a_vector

Loading…
Cancel
Save