[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