Hi,
After a user process calls back kernel (system call using CALL GATE), no IRQs are being fired (particularly TIMER) - while I have configured APIC which works fine before switching to user process
I recently started working on APIC. Though I haven't worked towards supporting multiple processors yet I got APIC working almost
I am able to configure APIC and also local timer to fire TIMER irq (0 -> mapped to 32)
Multiple (kernel) processes which all run in kernel space (ring0) run fine (scheduling works fine switching from one process to another upon timer irq)
However, when I do a task switch to a user process (ring3) and then when it calls back to kernel via a call gate, I notice that timer irq is not firing any more (actually no irqs) - and hence there is no context switch based on irq any more
With the same code base if I just switch back to using PIC then everything works fine
Can anyone please help !
[ This is on QEMU n I'm using hardware task switching ]
Regards,
- Prajwala
[SOLVED] APIC issue after CALL Gate
[SOLVED] APIC issue after CALL Gate
Last edited by prajwal on Wed Aug 10, 2016 3:11 am, edited 1 time in total.
complexity is the core of simplicity
Re: APIC issue after CALL Gate
As expected, this was some bug in my OS which survived this long but got caught while implementing APIC
Just in case if it helps others
Problem 1) Once I switch to a user process (ring 3, different page table), IRQs stop
Answer: This was a page mapping issue. The first "X" mb of my kernel is mapped 1 to 1 with user process. APIC base (0xFEE00000 and 0xFEC00000) are re-mapped to some area within this kernel space. But while creating page table for user process, I was doing 1 to 1 map without honoring the IO mapped area
Problem 2) On a real PC, there was no keyboard IRQ
Answer: My (now earlier) implementation to consume keyboard characters was to Disable Keyboard IRQ, read them off an internal queue, Enable Keyboard IRQ. This worked fine with PIC probably because by disabling/enabling IRQ, we won't lose the IRQ (?). However, with APIC, when I disabled IRQ, the IRQs are lost (I disable by writing to 0x10 + irqNo * 2 of apic base). On real PC, the foreground process executing this code sequence (i.e. disable KB irq, check/read queue, enable KB irq) was starving APIC and all IRQs were lost (this is my inference). I then changed the approach to use different synchronization approach w/o enable/disable IRQ that worked w/o any issues
Is there a way to disable APIC IRQ without losing them ?
Just in case if it helps others
Problem 1) Once I switch to a user process (ring 3, different page table), IRQs stop
Answer: This was a page mapping issue. The first "X" mb of my kernel is mapped 1 to 1 with user process. APIC base (0xFEE00000 and 0xFEC00000) are re-mapped to some area within this kernel space. But while creating page table for user process, I was doing 1 to 1 map without honoring the IO mapped area
Problem 2) On a real PC, there was no keyboard IRQ
Answer: My (now earlier) implementation to consume keyboard characters was to Disable Keyboard IRQ, read them off an internal queue, Enable Keyboard IRQ. This worked fine with PIC probably because by disabling/enabling IRQ, we won't lose the IRQ (?). However, with APIC, when I disabled IRQ, the IRQs are lost (I disable by writing to 0x10 + irqNo * 2 of apic base). On real PC, the foreground process executing this code sequence (i.e. disable KB irq, check/read queue, enable KB irq) was starving APIC and all IRQs were lost (this is my inference). I then changed the approach to use different synchronization approach w/o enable/disable IRQ that worked w/o any issues
Is there a way to disable APIC IRQ without losing them ?
complexity is the core of simplicity