[syslinux] [PATCH] pxe: Never chain to the original ISR
Retransmit
stappers at stappers.nl
Thu Mar 23 14:15:04 PDT 2017
Retransmit
On Sun, Mar 19, 2017 at 12:23:20PM +0000, Michael Brown via Syslinux wrote:
> The behaviour of default ISRs as provided by the BIOS varies wildly
> between platforms. Some will simply iret, some will send EOI, some
> will send EOI and disable the interrupt at the PIC, some will crash
> the machine due to single-bit errors in the ISR address.
>
> When PXENV_UNDI_ISR_IN_START returns PXENV_UNDI_ISR_OUT_NOT_OURS, send
> the EOI ourselves rather than risking the unpredictable behaviour of
> chaining to the original ISR.
>
> Signed-off-by: Michael Brown <mcb30 op ipxe.org>
> ---
> core/fs/pxe/isr.c | 5 +++--
> core/fs/pxe/pxe.h | 1 -
> core/pxeisr.inc | 17 ++++++-----------
> 3 files changed, 9 insertions(+), 14 deletions(-)
>
> diff --git a/core/fs/pxe/isr.c b/core/fs/pxe/isr.c
> index 7da0cc7..e14b953 100644
> --- a/core/fs/pxe/isr.c
> +++ b/core/fs/pxe/isr.c
> @@ -17,6 +17,7 @@ extern volatile uint8_t pxe_need_poll;
> static DECLARE_INIT_SEMAPHORE(pxe_receive_thread_sem, 0);
> static DECLARE_INIT_SEMAPHORE(pxe_poll_thread_sem, 0);
> static struct thread *pxe_thread, *poll_thread;
> +static far_ptr_t old_pxe_isr;
>
> #ifndef PXE_POLL_FORCE
> # define PXE_POLL_FORCE 0
> @@ -252,7 +253,7 @@ void pxe_start_isr(void)
> pxe_irq_vector = irq;
>
> if (irq) {
> - if (!install_irq_vector(irq, pxe_isr, &pxe_irq_chain))
> + if (!install_irq_vector(irq, pxe_isr, &old_pxe_isr))
> irq = 0; /* Install failed or stuck interrupt */
> }
>
> @@ -290,7 +291,7 @@ int reset_pxe(void)
> printf("PXENV_UNDI_CLOSE failed: 0x%x\n", undi_close.Status);
>
> if (pxe_irq_vector)
> - uninstall_irq_vector(pxe_irq_vector, pxe_isr, &pxe_irq_chain);
> + uninstall_irq_vector(pxe_irq_vector, pxe_isr, &old_pxe_isr);
> if (poll_thread)
> kill_thread(poll_thread);
>
> diff --git a/core/fs/pxe/pxe.h b/core/fs/pxe/pxe.h
> index 19664f9..449391b 100644
> --- a/core/fs/pxe/pxe.h
> +++ b/core/fs/pxe/pxe.h
> @@ -212,7 +212,6 @@ static inline uint32_t gateway(uint32_t ip)
> /* pxeisr.inc */
> extern uint8_t pxe_irq_vector;
> extern void pxe_isr(void);
> -extern far_ptr_t pxe_irq_chain;
> extern void pxe_poll(void);
>
> /* isr.c */
> diff --git a/core/pxeisr.inc b/core/pxeisr.inc
> index 93c73ed..36e83f2 100644
> --- a/core/pxeisr.inc
> +++ b/core/pxeisr.inc
> @@ -40,7 +40,7 @@ pxe_isr:
> ; leftover BC doesn't get control.
> mov byte [pxe_irq_pending],1
> inc dword [pxe_irq_count]
> -
> +.eoi:
> cmp byte [pxe_irq_vector], 8
> mov al,0x20 ; Non-specific EOI
> jb .pri_pic
> @@ -66,20 +66,15 @@ pxe_isr:
> dec word [pxeirq_deadman]
> jz .timeout
>
> -.chain:
> - pop gs
> - pop fs
> - pop es
> - pop ds
> - popa
> - jmp 0:0
> - global pxe_irq_chain
> -pxe_irq_chain equ $-4
> + ; Even though it isn't ours, we still need to send the
> + ; EOI ourselves, since chaining to the original
> + ; handler is too risky.
> + jmp .eoi
>
> .reset_timeout:
> mov [pxeirq_last],ax
> mov word [pxeirq_deadman],PXEIRQ_MAX
> - jmp .chain
> + jmp .eoi
>
> ; Too many spurious interrupts, shut off the interrupts
> ; and go to polling mode
> --
> 2.9.3
>
> _______________________________________________
> Syslinux mailing list
> Submissions to Syslinux op zytor.com
> Unsubscribe or set options at:
> http://www.zytor.com/mailman/listinfo/syslinux
More information about the Syslinux
mailing list