Page 1 of 1
General Protection exception when popping from the stack
Posted: Wed May 15, 2024 10:09 pm
by Arpanoid
Hello,
I have a strange problem: one of my test hardware, which is HP EliteBook CORE i5, throws sometimes a #GP exception in the 32bit protected mode at a specific place in the code. The instruction generating the exception and the preceeding one are
First of all, looking into the intel manual I can't see how pop edx can get #GP. I would rather expect #SS.
Second, it's werid that it's thrown not every time but sometimes.
I'm not sure if more detailed context could be of any help here, but just in case:
1. Those two instructions are at the end of the subrouting which sends commands to the PS/2 keyboard controller.
2. When this subroutine is called from the kernel initialization (interrupts disabled yet), there's no problem
3. After that, the only case I need to send commands to the controller is to light the keyboard LEDs when a user presses one of the keyboard locks (for example, CapsLock). But the exception is generated not every lock press.
4. The exception error code is 0x1BB every time.
5. I tried to insert a call to a kind of diagnostic output subroutine before the popfd - the problem dissapeared.
6. I tested the same code on another laptop - HP Pavilion with CORE i5 CPU and never had this exception there.
I would appreciate any ideas about what could cause this problem.
Thanks
Re: General Protection exception when popping from the stack
Posted: Wed May 15, 2024 10:57 pm
by MichaelPetch
I wonder if the POPFD re-enabled interrupts and the pop edx ended up being the instruction where the interrupt was raised. Error code 0x1BB (if accurate) would suggest that there was #GP exception and the descriptor is in the IDT 0x1BB>>3 is index 0x37. Where did you remap your external interrupts (the master and slave PICs) to?
Re: General Protection exception when popping from the stack
Posted: Wed May 15, 2024 11:08 pm
by Octocontrabass
Error code 0x1BB means you've received an IRQ that's mapped to interrupt vector 0x37, but your IDT doesn't have a valid descriptor.
Which IRQ uses interrupt vector 0x37? Is it IRQ7? If it is, it might be a spurious interrupt.
How are you receiving the response from the keyboard controller after you send the commands? Are you polling? If you are, you might be acknowledging the keyboard controller's IRQ before the interrupt controller can send it to you. Acknowledging an interrupt before the interrupt controller can send it to you can cause a spurious IRQ. Spurious IRQs appear as IRQ7 and IRQ15.
Re: General Protection exception when popping from the stack
Posted: Sat May 18, 2024 1:52 pm
by Arpanoid
MichaelPetch wrote:I wonder if the POPFD re-enabled interrupts and the pop edx ended up being the instruction where the interrupt was raised. Error code 0x1BB (if accurate) would suggest that there was #GP exception and the descriptor is in the IDT 0x1BB>>3 is index 0x37. Where did you remap your external interrupts (the master and slave PICs) to?
Octocontrabass wrote:Error code 0x1BB means you've received an IRQ that's mapped to interrupt vector 0x37, but your IDT doesn't have a valid descriptor.
Which IRQ uses interrupt vector 0x37? Is it IRQ7? If it is, it might be a spurious interrupt.
Yes, indeed, my PICs are mapped to the vectors 0x30 - 0x3F. I created a handler for the IRQ7 and added the corresponding descriptor to the IDT and now this handler is called instead of the exception handler. Unfortunately, the Intel manual is not clear in #GP reference article. It says "vector number" but in reality, as I learned from your replies, it's the descriptor offset from the beginning of the IDT.
Octocontrabass wrote:How are you receiving the response from the keyboard controller after you send the commands? Are you polling? If you are, you might be acknowledging the keyboard controller's IRQ before the interrupt controller can send it to you. Acknowledging an interrupt before the interrupt controller can send it to you can cause a spurious IRQ. Spurious IRQs appear as IRQ7 and IRQ15.
Yes, I'm polling. But I'm not quite sure if acknowledging an IRQ is the case. Anyway, I clear IF in EFLAGS before starting the communication with the keyboard controller. I also checked the exchange between my code and the controller: it always replies 0xFA for both the 0xED command and to the data byte. I would expect other response if it was acknowledging an IRQ. I rather tend to believe that there's something wrong with the hardware. I bought this laptop refurbished and it started behavins weird after just a couple of weeks. So, certainly something is wrong with it.
Thanks to everyone very much for your help!
Re: General Protection exception when popping from the stack
Posted: Sat May 18, 2024 2:17 pm
by Octocontrabass
Arpanoid wrote:Anyway, I clear IF in EFLAGS before starting the communication with the keyboard controller.
Clearing EFLAGS.IF just means the CPU ignores the interrupt controller. The keyboard controller still asserts its interrupt line, and the interrupt controller tries to interrupt the CPU while that interrupt line is asserted.
Arpanoid wrote:I also checked the exchange between my code and the controller: it always replies 0xFA for both the 0xED command and to the data byte. I would expect other response if it was acknowledging an IRQ.
The response has nothing to do with it. The keyboard controller asserts its interrupt line for
every byte, not just bytes received from the keyboard.
Arpanoid wrote:I rather tend to believe that there's something wrong with the hardware. I bought this laptop refurbished and it started behavins weird after just a couple of weeks. So, certainly something is wrong with it.
There could be something else wrong with the hardware, but this spurious interrupt is caused by polling the keyboard controller. You can prevent the spurious interrupt by using IRQ1 to receive the response from the keyboard controller instead of polling.
Re: General Protection exception when popping from the stack
Posted: Mon May 20, 2024 9:40 pm
by Arpanoid
Arpanoid wrote:You can prevent the spurious interrupt by using IRQ1 to receive the response from the keyboard controller instead of polling.
I would like to avoid this approach to keep the driver design simple. I wonder if temporary disabling the IRQ1 in the interrupt controller can help or it will have the same effect as EFLAGS.IF? Or, maybe disabling first port interrupts in the PS/2 controller will help? I'll maybe try this later. For a while I just check in IRQ7 and IRQ15 handlers if this is a spurious interrupt.
Re: General Protection exception when popping from the stack
Posted: Mon May 20, 2024 11:12 pm
by Octocontrabass
Arpanoid wrote:I would like to avoid this approach to keep the driver design simple.
Receiving the response with your IRQ handler is the simplest way to avoid spurious IRQs.
Arpanoid wrote:I wonder if temporary disabling the IRQ1 in the interrupt controller can help or it will have the same effect as EFLAGS.IF?
It will have the same effect, but the timing will be different, so you may not see spurious IRQs on the same hardware.
Arpanoid wrote:Or, maybe disabling first port interrupts in the PS/2 controller will help?
That sounds like a good way to lose scan codes.
Re: General Protection exception when popping from the stack
Posted: Wed May 22, 2024 6:20 am
by Jiyahana
Hey hi, It's unusual for the pop edx instruction to generate a GP exception. Check for errors in the code and compare system configurations between the elitebook and the HP pavilion.
Re: General Protection exception when popping from the stack
Posted: Wed May 22, 2024 7:20 pm
by Arpanoid
Octocontrabass wrote:Receiving the response with your IRQ handler is the simplest way to avoid spurious IRQs.
It's probably the simplest way to avoid the spurios interrupts but not the simplest driver design in general. With this approach the sending-command functionality has to be split between the interrupt handler and another subroutine (which will do the send part) - doesn't look for me like simpler design than what I have currently. Also, checking if it's a spurious interrupt in IRQ7 and IRQ15 is not complicated neither.
I would like to understand your point. Do I miss something? Could you elaborate a bit more on the advantages of the approach #1 (receiving the keyboard response with the IRQ1 handler) comparing to the approach #2 (using IRQ7 and IRQ15 handlers and checking if the interrupt is spurious)?
Re: General Protection exception when popping from the stack
Posted: Wed May 22, 2024 10:57 pm
by Octocontrabass
Arpanoid wrote:Could you elaborate a bit more on the advantages of the approach #1 (receiving the keyboard response with the IRQ1 handler) comparing to the approach #2 (using IRQ7 and IRQ15 handlers and checking if the interrupt is spurious)?
Mostly it's the same advantage any driver gets from using interrupts instead of polling: it allows the CPU to do something useful while you wait for hardware to respond. The keyboard might feel fast to you, but it could take several milliseconds to receive a response after you send a command, and that's millions of CPU cycles you could spend not polling the keyboard controller.
Also, broken hardware can sometimes cause spurious IRQs, but if you have a driver that causes spurious IRQs, you might not notice the hardware problem.
Re: General Protection exception when popping from the stack
Posted: Thu May 23, 2024 4:44 pm
by Arpanoid
Octocontrabass wrote:Mostly it's the same advantage any driver gets from using interrupts instead of polling: it allows the CPU to do something useful while you wait for hardware to respond. The keyboard might feel fast to you, but it could take several milliseconds to receive a response after you send a command, and that's millions of CPU cycles you could spend not polling the keyboard controller.
Also, broken hardware can sometimes cause spurious IRQs, but if you have a driver that causes spurious IRQs, you might not notice the hardware problem.
I see. At my current stage of development the perfomance concerns are not critical but they will eventually become critical with the system growth. So, it's a good point. Thank you for sharing your ideas!