summaryrefslogtreecommitdiffstats
path: root/src/arch
diff options
context:
space:
mode:
authorH. Peter Anvin2008-02-09 01:19:02 +0100
committerMichael Brown2008-02-11 16:09:47 +0100
commitfc9f016be09cff82bfb06fe2c6e13e4f7ab1fce7 (patch)
tree5dd0884ad92add0ff13932146009fa498900715b /src/arch
parentUse internal 16-bit stack for added safety. (diff)
downloadipxe-fc9f016be09cff82bfb06fe2c6e13e4f7ab1fce7.tar.gz
ipxe-fc9f016be09cff82bfb06fe2c6e13e4f7ab1fce7.tar.xz
ipxe-fc9f016be09cff82bfb06fe2c6e13e4f7ab1fce7.zip
UNDI ISR: save and restore 32-bit registers
As written, if the if the UNDI ISR call clobbers the upper halves of any of the GPRs (which by convention it is permitted to do, and by paranoia should be expected to do) then nothing in the interrupt handler will recover the state. Additionally, save/restore %fs and %gs out of sheer paranoia - it's a cheap enough operation, and may prevent problems due to poorly written UNDI stacks.
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/i386/drivers/net/undiisr.S11
1 files changed, 7 insertions, 4 deletions
diff --git a/src/arch/i386/drivers/net/undiisr.S b/src/arch/i386/drivers/net/undiisr.S
index 24630148..15e1a63a 100644
--- a/src/arch/i386/drivers/net/undiisr.S
+++ b/src/arch/i386/drivers/net/undiisr.S
@@ -21,7 +21,9 @@ undiisr:
/* Preserve registers */
pushw %ds
pushw %es
- pusha
+ pushw %fs
+ pushw %gs
+ pushal
/* Set up our segment registers */
movw %cs:rm_ds, %ax
@@ -32,8 +34,7 @@ undiisr:
je chain
/* Issue UNDI API call */
- pushw %ds
- popw %es
+ movw %ax, %es
movw $undinet_params, %di
movw $PXENV_UNDI_ISR, %bx
movw $PXENV_UNDI_ISR_IN_START, funcflag
@@ -62,7 +63,9 @@ chain: /* Chain to next handler */
lcall *undiisr_next_handler
exit: /* Restore registers and return */
- popa
+ popal
+ popw %gs
+ popw %fs
popw %es
popw %ds
iret