What happened from KfLowerIrql to HalpDispatchInterrupt

Hi, all:

Here is a stack trace of winDBG

kd> k
ChildEBP RetAddr
f8a05cc0 806efa86 nt!KiDispatchInterrupt
f8a05cc0 806ef2e7 hal!HalpDispatchInterrupt+0xba
f8a05d38 804dd6bc hal!KfLowerIrql+0x17
f8a05d44 804dd6f2 nt!KiSwapThread+0x68
f8a05d6c f814eed2 nt!KeWaitForSingleObject+0x1c2
f8a05dac 8057efed USBPORT!USBPORT_WorkerThread+0x3c
f8a05ddc 804fb477 nt!PspSystemThreadStartup+0x34
00000000 00000000 nt!KiThreadStartup+0x16

hal!KfLowerIrql:
806ef2d0 33c0 xor eax,eax
806ef2d2 8ac1 mov al,cl
806ef2d4 33c9 xor ecx,ecx
806ef2d6 8a8858f26e80 mov cl,byte ptr hal!HalpIRQLtoTPR
(806ef258)[eax]
806ef2dc 890d8000feff mov dword ptr ds:[0FFFE0080h],ecx
806ef2e2 a18000feff mov eax,dword ptr ds:[FFFE0080h]
806ef2e7 c3 ret

hal!KfLowerIrql doesn’t call hal!HalpDispatchInterrupt directly, so what
happened after
mov eax,dword ptr ds:[FFFE0080h]
instruction?

I know this is a silly question, but I still cannot understand the
software interrupt mechanism.
Because KfLowerIrql code is currently running on the processor, other
code will not be execute (on a UP system) until
Context switch or other hardware interrupt. Is this right? Why the
proccessor know there is a software intterrupt request and
process it ?

Thanks for all replies.

-A

At any given interrupt level, all of the lower level interrupts are blocked (either virtually for software interrupts or physically in the PIC/APIC hardware for hardware interrupts). KfLowerIrql drops the IRQL and part of this is unblocking any interrupts which would be >= the new IRQL. If an interrupt is pending it will be delivered any time after this happens, even right in the middle of KfLowerIrql.

KfLowerIrql doesn’t do anything to stop interrupts from happening - blocked interrupts are a side effect of your current IRQL, not of whatever functions you’re running at the time. If you were at APC_LEVEL then you could still get rescheduled (APC_LEVEL is less than DISPATCH_LEVEL, and it’s DISPATCH_LEVEL or greater that blocks rescheduling).

-p


From: xxxxx@lists.osr.com on behalf of Anders Parker
Sent: Wed 9/13/2006 5:10 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] What happened from KfLowerIrql to HalpDispatchInterrupt

Hi, all:

Here is a stack trace of winDBG

kd> k
ChildEBP RetAddr
f8a05cc0 806efa86 nt!KiDispatchInterrupt
f8a05cc0 806ef2e7 hal!HalpDispatchInterrupt+0xba
f8a05d38 804dd6bc hal!KfLowerIrql+0x17
f8a05d44 804dd6f2 nt!KiSwapThread+0x68
f8a05d6c f814eed2 nt!KeWaitForSingleObject+0x1c2
f8a05dac 8057efed USBPORT!USBPORT_WorkerThread+0x3c
f8a05ddc 804fb477 nt!PspSystemThreadStartup+0x34
00000000 00000000 nt!KiThreadStartup+0x16

hal!KfLowerIrql:
806ef2d0 33c0 xor eax,eax
806ef2d2 8ac1 mov al,cl
806ef2d4 33c9 xor ecx,ecx
806ef2d6 8a8858f26e80 mov cl,byte ptr hal!HalpIRQLtoTPR (806ef258)[eax]
806ef2dc 890d8000feff mov dword ptr ds:[0FFFE0080h],ecx
806ef2e2 a18000feff mov eax,dword ptr ds:[FFFE0080h]
806ef2e7 c3 ret

hal!KfLowerIrql doesn’t call hal!HalpDispatchInterrupt directly, so what happened after
mov eax,dword ptr ds:[FFFE0080h]
instruction?

I know this is a silly question, but I still cannot understand the software interrupt mechanism.
Because KfLowerIrql code is currently running on the processor, other code will not be execute (on a UP system) until
Context switch or other hardware interrupt. Is this right? Why the proccessor know there is a software intterrupt request and
process it ?

Thanks for all replies.

-A
— Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256 To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Thank Peter for replying. However, there might be some misunderstanding and
maybe that is because I did not describe the problem clearly enough. And I
am sorry for that.

When a hardware interrupt occurs, the CPU is informed by the APIC through
the interrupt line. But there is no such mechanism and no corresponding
interrupt line for software interrupt. How does the CPU know a software
interrupt occurs?

If we queued an IsrForDpc routine during the hardware interrupt processing,
we use the KeLowerIrql function to lower the IRQL from DPC_LEVEL to APC or
PASSIVE LEVEL. But because the KeLowerlrql does not call the
KiDispatchInterrupt function, the problem is, how does the CPU know
immediately that there is a software interrupt waiting for processing?

*BTW, I found the following words in the Windows Internal:
The kernel always raises the processor’s IRQL to DPC/dispatch level or above
when it needs to synchronize access to shared kernel structures. This
disables additional software interrupts and thread dispatching*.

Since KeRaiseIrql does not modify APIC and just sets the corresponding parts
of PCR, how does the OS mask the hardware interrupt?

> When a hardware interrupt occurs, the CPU is informed by the APIC through

the interrupt line. But there is no such mechanism and no corresponding
interrupt line for software interrupt. How does the CPU know a software
interrupt occurs?

I think that the software interrupts (IRQL changes to DISPATCH and such) are
either triggered by writing something to APIC, or just plain emulated in HAL
software. Anyway this is the job of HAL.

PASSIVE LEVEL. But because the KeLowerlrql does not call the
KiDispatchInterrupt function, the problem is, how does the CPU know
immediately that there is a software interrupt waiting for processing?

KeLowerIrql is in the HAL, and is the part of this HAL’s mechanism I described
above.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

Just to be clear, you cannot lower the IRQL of your DPC to ACP or
PASSIVE_LEVEL. The only time you are allowed to call KeLowerIrql is if
you previously called KeRaiseIrql. To reiterate, if your function was
invoked at a specific IRQL level by a component outside of your driver
(e.g. a DPC or a completion routine) and the IRQL is not what you need,
you are not allowed to lower it (instead you should queue a work item).

d

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Anders Parker
Sent: Thursday, September 14, 2006 2:05 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] What happened from KfLowerIrql to
HalpDispatchInterrupt

Thank Peter for replying. However, there might be some misunderstanding
and maybe that is because I did not describe the problem clearly enough.
And I am sorry for that.
When a hardware interrupt occurs, the CPU is informed by the APIC
through the interrupt line. But there is no such mechanism and no
corresponding interrupt line for software interrupt. How does the CPU
know a software interrupt occurs?
If we queued an IsrForDpc routine during the hardware interrupt
processing, we use the KeLowerIrql function to lower the IRQL from
DPC_LEVEL to APC or PASSIVE LEVEL. But because the KeLowerlrql does not
call the KiDispatchInterrupt function, the problem is, how does the CPU
know immediately that there is a software interrupt waiting for
processing?
BTW, I found the following words in the Windows Internal:
The kernel always raises the processor’s IRQL to DPC/dispatch level or
above when it needs to synchronize access to shared kernel structures.
This disables additional software interrupts and thread dispatching .
Since KeRaiseIrql does not modify APIC and just sets the corresponding
parts of PCR, how does the OS mask the hardware interrupt?
— Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256 To unsubscribe, visit the
List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Since software interrupts only happen because software requested them,
it’s easy enough to record that you wanted to run an interrupt on a
particular CPU somewhere (in the PCR perhaps) and then to have
KeLowerIrql check for that and simulate the interrupt.

I also thought that the APIC could be set to trigger a software
interrupt too, but that’s getting into HAL territory and I know less
about the HAL.

-p

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Anders Parker
Sent: Thursday, September 14, 2006 2:05 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] What happened from KfLowerIrql to
HalpDispatchInterrupt

Thank Peter for replying. However, there might be some misunderstanding
and maybe that is because I did not describe the problem clearly enough.
And I am sorry for that.

When a hardware interrupt occurs, the CPU is informed by the APIC
through the interrupt line. But there is no such mechanism and no
corresponding interrupt line for software interrupt. How does the CPU
know a software interrupt occurs?

If we queued an IsrForDpc routine during the hardware interrupt
processing, we use the KeLowerIrql function to lower the IRQL from
DPC_LEVEL to APC or PASSIVE LEVEL. But because the KeLowerlrql does not
call the KiDispatchInterrupt function, the problem is, how does the CPU
know immediately that there is a software interrupt waiting for
processing?

BTW, I found the following words in the Windows Internal:
The kernel always raises the processor’s IRQL to DPC/dispatch level or
above when it needs to synchronize access to shared kernel structures.
This disables additional software interrupts and thread dispatching .

Since KeRaiseIrql does not modify APIC and just sets the corresponding
parts of PCR, how does the OS mask the hardware interrupt?

— Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256 To unsubscribe, visit the
List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Maxim S. Shatskih wrote:

>When a hardware interrupt occurs, the CPU is informed by the APIC through
>the interrupt line. But there is no such mechanism and no corresponding
>interrupt line for software interrupt. How does the CPU know a software
>interrupt occurs?
>
>

I think that the software interrupts (IRQL changes to DISPATCH and such) are
either triggered by writing something to APIC, or just plain emulated in HAL
software. Anyway this is the job of HAL.

I don’t think his question was at that level. I think it was more
fundamental.

To the OP, this answer should be obvious. The CPU knows a software
interrupt occurred because it was the CPU that executed a software
interrupt instruction. A hardware interrupt comes from outside the CPU
– someone has to notify the CPU to take some action. But when you
execute an “INT 2F”, the CPU is in complete control. It just starts
doing whatever it would have done when it saw a hardware interrupt.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Anders Parker wrote:

Thank Peter for replying. However, there might be some
misunderstanding and maybe that is because I did not describe the
problem clearly enough. And I am sorry for that.

When a hardware interrupt occurs, the CPU is informed by the APIC
through the interrupt line. But there is no such mechanism and no
corresponding interrupt line for software interrupt. How does the CPU
know a software interrupt occurs?

If we queued an IsrForDpc routine during the hardware interrupt
processing, we use the KeLowerIrql function to lower the IRQL from
DPC_LEVEL to APC or PASSIVE LEVEL. But because the KeLowerlrql does
not call the KiDispatchInterrupt function, the problem is, how does
the CPU know immediately that there is a software interrupt waiting
for processing?

There CANNOT BE a software interrupt “waiting for processing”. A
software interrupt is an executable instruction. When the CPU
encounters one, an interrupt happens immediately. IRQLs, APICs, and
even the interrupt enable flag are all irrelevant. When you execute an
INT instruction, you’ll do a far call to an interrupt handler, right now.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

It depends on what you mean by software interrupt. If you mean an _int
instruction you’re correct. If you’re talking about the concept of DPCs
which are described as behaving like interrupts but are triggered in
software, or interrupt levels like APC and DPC which don’t necessarily
correspond to anything on the PIC/APCI then they can most definitely be
deferred.

-p

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Tim Roberts
Sent: Thursday, September 14, 2006 11:30 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] What happened from KfLowerIrql to
HalpDispatchInterrupt

Anders Parker wrote:

Thank Peter for replying. However, there might be some
misunderstanding and maybe that is because I did not describe the
problem clearly enough. And I am sorry for that.

When a hardware interrupt occurs, the CPU is informed by the APIC
through the interrupt line. But there is no such mechanism and no
corresponding interrupt line for software interrupt. How does the CPU
know a software interrupt occurs?

If we queued an IsrForDpc routine during the hardware interrupt
processing, we use the KeLowerIrql function to lower the IRQL from
DPC_LEVEL to APC or PASSIVE LEVEL. But because the KeLowerlrql does
not call the KiDispatchInterrupt function, the problem is, how does
the CPU know immediately that there is a software interrupt waiting
for processing?

There CANNOT BE a software interrupt “waiting for processing”. A
software interrupt is an executable instruction. When the CPU
encounters one, an interrupt happens immediately. IRQLs, APICs, and
even the interrupt enable flag are all irrelevant. When you execute an
INT instruction, you’ll do a far call to an interrupt handler, right
now.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Because KeLowerIrql called KfLowerIrql, I examined KfLowerIrql with WinDBG
and found that the function contained no code that could check IRQL and
simulate software interrupt. See below:

kd> uf hal!KfLowerIrql
hal!KfLowerIrql:
806ef2d0 33c0 xor eax,eax
806ef2d2 8ac1 mov al,cl
806ef2d4 33c9 xor ecx,ecx
806ef2d6 8a8858f26e80 mov cl,byte ptr hal!HalpIRQLtoTPR
(806ef258)[eax]
806ef2dc 890d8000feff mov dword ptr ds:[0FFFE0080h],ecx
806ef2e2 a18000feff mov eax,dword ptr ds:[FFFE0080h]
806ef2e7 c3 ret

However, the strange thing is, the system called hal!HalpDispatchInterrupt
to handle the DPC before the KeLowerIrq function returned. So, what happed
between the hal!KfLowerIrql and hal!HalpDispatchInterrupt? See below:

ChildEBP RetAddr
f8a05cc0 806efa86 nt!KiDispatchInterrupt
f8a05cc0 806ef2e7 hal!HalpDispatchInterrupt+0xba
f8a05d38 804dd6bc hal!KfLowerIrql+0x17
f8a05d44 804dd6f2 nt!KiSwapThread+0x68
f8a05d6c f814eed2 nt!KeWaitForSingleObject+0x1c2
f8a05dac 8057efed USBPORT!USBPORT_WorkerThread+0x3c
f8a05ddc 804fb477 nt!PspSystemThreadStartup+0x34
00000000 00000000 nt!KiThreadStartup+0x16

On 9/15/06, Peter Wieland wrote:
>
> Since software interrupts only happen because software requested them,
> it’s easy enough to record that you wanted to run an interrupt on a
> particular CPU somewhere (in the PCR perhaps) and then to have KeLowerIrql
> check for that and simulate the interrupt.
>
>
>
> I also thought that the APIC could be set to trigger a software interrupt
> too, but that’s getting into HAL territory and I know less about the HAL.
>
>
>
> -p
>
>
>
> From: xxxxx@lists.osr.com [mailto:
> xxxxx@lists.osr.com] *On Behalf Of *Anders Parker
> Sent: Thursday, September 14, 2006 2:05 AM
>
> To: Windows System Software Devs Interest List
> Subject: Re: [ntdev] What happened from KfLowerIrql to
> HalpDispatchInterrupt
>
>
>
> Thank Peter for replying. However, there might be some misunderstanding
> and maybe that is because I did not describe the problem clearly enough. And
> I am sorry for that.
>
> When a hardware interrupt occurs, the CPU is informed by the APIC through
> the interrupt line. But there is no such mechanism and no corresponding
> interrupt line for software interrupt. How does the CPU know a software
> interrupt occurs?
>
> If we queued an IsrForDpc routine during the hardware interrupt
> processing, we use the KeLowerIrql function to lower the IRQL from DPC_LEVEL
> to APC or PASSIVE LEVEL. But because the KeLowerlrql does not call the
> KiDispatchInterrupt function, the problem is, how does the CPU know
> immediately that there is a software interrupt waiting for processing?
>
> *BTW, I found the following words in the Windows Internal:**
> The kernel always raises the processor’s IRQL to DPC/dispatch level or
> above when it needs to synchronize access to shared kernel structures.This disables additional software interrupts and thread dispatching
> *.
>
> Since KeRaiseIrql does not modify APIC and just sets the corresponding
> parts of PCR, how does the OS mask the hardware interrupt?
>
> — Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256 To unsubscribe, visit the List
> Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

As far as I know, when the DIRQL handles hardware interrupts, driver usually
calls KeInsertQueueDpc to enqueue an IsrForDpc routine and then requests a
software interrupt of DPC LEVEL through the hal!HalRequestSoftwareInterrupt
function. When the IRQL of CPU becomes APC or PASSIVE LEVEL, the CPU will
know the existence of and go to handle software interrupts of DPC LEVEL.

However, I find that none of the three functions, KeInsertQueueDpc,
HalRequestSoftwareInterrupt and KeLowerIrql, sets APIC/PIC. So, how does
the CPU knows there is a software interrupt?

What’s more, let’s see the stack below. The KfLowerIrql is being executed
and occupying the CPU, so the other code of HAL should not be able to
simulate a software interrupt. So, why can it call the
hal!HalpDispatchInterrupt ?

ChildEBP RetAddr
f8a05cc0 806efa86 nt!KiDispatchInterrupt
f8a05cc0 806ef2e7 hal!HalpDispatchInterrupt+0xba
f8a05d38 804dd6bc hal!KfLowerIrql+0x17
f8a05d44 804dd6f2 nt!KiSwapThread+0x68
f8a05d6c f814eed2 nt!KeWaitForSingleObject+0x1c2
f8a05dac 8057efed USBPORT!USBPORT_WorkerThread+0x3c
f8a05ddc 804fb477 nt!PspSystemThreadStartup+0x34
00000000 00000000 nt!KiThreadStartup+0x16

On 9/14/06, Maxim S. Shatskih wrote:
>
> > When a hardware interrupt occurs, the CPU is informed by the APIC
> through
> > the interrupt line. But there is no such mechanism and no corresponding
> > interrupt line for software interrupt. How does the CPU know a software
> > interrupt occurs?
>
> I think that the software interrupts (IRQL changes to DISPATCH and such)
> are
> either triggered by writing something to APIC, or just plain emulated in
> HAL
> software. Anyway this is the job of HAL.
>
> > PASSIVE LEVEL. But because the KeLowerlrql does not call the
> > KiDispatchInterrupt function, the problem is, how does the CPU know
> > immediately that there is a software interrupt waiting for processing?
>
> KeLowerIrql is in the HAL, and is the part of this HAL’s mechanism I
> described
> above.
>
> Maxim Shatskih, Windows DDK MVP
> StorageCraft Corporation
> xxxxx@storagecraft.com
> http://www.storagecraft.com
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

What happened between them? It’s called an interrupt!

Perhaps this will clarify it for you:

(1) Look at the return addresses on the stack. It says KfLowerIrql was interrupted just before its return instruction was executed.

(2) Why was it interrupted? Because every subroutine in creation has to have done its work before you execute its return instruction. So IRQL is already APC level, meaning you have enabled DPC dispatching and all of the hardware interrupt mechanisms.

(3) How was it interrupted? Well, there’s a memory-mapped register in the APIC called the TPR (Task Priority Register), and you just updated it through a table pointer named HalpIRQLToTPR. So a reasonable inference is, just as several people have said, this routine has finished telling the APIC it can dispatch all that stuff its been holding back on.

(4) Why don’t you see code that calls HalpDispatchInterrupt? Because the hardware interrupt process for any microprocessor changes the instruction pointer- like say to HalpDispatchInterrupt? This doesn’t have to be the case, and is one reason there is a HAL. I believe the IA-32 still uses the IDT and the APIC sends an interrupt number to the processor as part of the interrupt cycle, which is then used as an index to the IDT. But no matter- whereever it goes, that code can do as it wishes, clean up its stack stuff, and then send you longjmp style to HalpDispatchInterrupt, all with interrupts disabled, and what would be different on your stack?

The basic point here is you can’t expect to see more of the interrupt trail than this from the stack.

I think that the DPC interrupt is scheduled via APIC hardware someway, and
KfLowerIrql definitely play with this hardware. After this play, the hardware
fires an interrupt, which is routed to HalpDispatchInterrupt.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

----- Original Message -----
From: “Anders Parker”
To: “Windows System Software Devs Interest List”
Sent: Friday, September 15, 2006 1:53 PM
Subject: Re: [ntdev] What happened from KfLowerIrql to HalpDispatchInterrupt

> Because KeLowerIrql called KfLowerIrql, I examined KfLowerIrql with WinDBG
> and found that the function contained no code that could check IRQL and
> simulate software interrupt. See below:
>
> kd> uf hal!KfLowerIrql
> hal!KfLowerIrql:
> 806ef2d0 33c0 xor eax,eax
> 806ef2d2 8ac1 mov al,cl
> 806ef2d4 33c9 xor ecx,ecx
> 806ef2d6 8a8858f26e80 mov cl,byte ptr hal!HalpIRQLtoTPR
> (806ef258)[eax]
> 806ef2dc 890d8000feff mov dword ptr ds:[0FFFE0080h],ecx
> 806ef2e2 a18000feff mov eax,dword ptr ds:[FFFE0080h]
> 806ef2e7 c3 ret
>
>
> However, the strange thing is, the system called hal!HalpDispatchInterrupt
> to handle the DPC before the KeLowerIrq function returned. So, what happed
> between the hal!KfLowerIrql and hal!HalpDispatchInterrupt? See below:
>
> ChildEBP RetAddr
> f8a05cc0 806efa86 nt!KiDispatchInterrupt
> f8a05cc0 806ef2e7 hal!HalpDispatchInterrupt+0xba
> f8a05d38 804dd6bc hal!KfLowerIrql+0x17
> f8a05d44 804dd6f2 nt!KiSwapThread+0x68
> f8a05d6c f814eed2 nt!KeWaitForSingleObject+0x1c2
> f8a05dac 8057efed USBPORT!USBPORT_WorkerThread+0x3c
> f8a05ddc 804fb477 nt!PspSystemThreadStartup+0x34
> 00000000 00000000 nt!KiThreadStartup+0x16
>
>
> On 9/15/06, Peter Wieland wrote:
> >
> > Since software interrupts only happen because software requested them,
> > it’s easy enough to record that you wanted to run an interrupt on a
> > particular CPU somewhere (in the PCR perhaps) and then to have KeLowerIrql
> > check for that and simulate the interrupt.
> >
> >
> >
> > I also thought that the APIC could be set to trigger a software interrupt
> > too, but that’s getting into HAL territory and I know less about the HAL.
> >
> >
> >
> > -p
> >
> >
> >
> > From: xxxxx@lists.osr.com [mailto:
> > xxxxx@lists.osr.com] *On Behalf Of *Anders Parker
> > Sent: Thursday, September 14, 2006 2:05 AM
> >
> > To: Windows System Software Devs Interest List
> > Subject: Re: [ntdev] What happened from KfLowerIrql to
> > HalpDispatchInterrupt
> >
> >
> >
> > Thank Peter for replying. However, there might be some misunderstanding
> > and maybe that is because I did not describe the problem clearly enough.
And
> > I am sorry for that.
> >
> > When a hardware interrupt occurs, the CPU is informed by the APIC through
> > the interrupt line. But there is no such mechanism and no corresponding
> > interrupt line for software interrupt. How does the CPU know a software
> > interrupt occurs?
> >
> > If we queued an IsrForDpc routine during the hardware interrupt
> > processing, we use the KeLowerIrql function to lower the IRQL from
DPC_LEVEL
> > to APC or PASSIVE LEVEL. But because the KeLowerlrql does not call the
> > KiDispatchInterrupt function, the problem is, how does the CPU know
> > immediately that there is a software interrupt waiting for processing?
> >
> > *BTW, I found the following words in the Windows Internal:**
> > The kernel always raises the processor’s IRQL to DPC/dispatch level or
> > above when it needs to synchronize access to shared kernel structures.This
disables additional software interrupts and thread dispatching
> > *.
> >
> > Since KeRaiseIrql does not modify APIC and just sets the corresponding
> > parts of PCR, how does the OS mask the hardware interrupt?
> >
> > — Questions? First check the Kernel Driver FAQ at
> > http://www.osronline.com/article.cfm?id=256 To unsubscribe, visit the List
> > Server section of OSR Online at
> > http://www.osronline.com/page.cfm?name=ListServer
> >
> > —
> > Questions? First check the Kernel Driver FAQ at
> > http://www.osronline.com/article.cfm?id=256
> >
> > To unsubscribe, visit the List Server section of OSR Online at
> > http://www.osronline.com/page.cfm?name=ListServer
> >
>
> —
> Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
>
> To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

This instruction:

806ef2d6 8a8858f26e80 mov cl,byte ptr hal!HalpIRQLtoTPR
(806ef258)[eax]

touched the APIC. It lowered the interrupt task priority register, which
unmasked the pending self-interrupt. Thus the APIC delivered it to the
processor. See Intel’s Programmer’s Reference Manual, Volume 3 Chapter 8.
All will be explained. (Available at http://developer.intel.com)

  • Jake Oshins
    Windows Kernel Team
    (Former owner of this code.)

“Anders Parker” wrote in message news:xxxxx@ntdev…
Because KeLowerIrql called KfLowerIrql, I examined KfLowerIrql with WinDBG
and found that the function contained no code that could check IRQL and
simulate software interrupt. See below:
kd> uf hal!KfLowerIrql
hal!KfLowerIrql:
806ef2d0 33c0 xor eax,eax
806ef2d2 8ac1 mov al,cl
806ef2d4 33c9 xor ecx,ecx
806ef2d6 8a8858f26e80 mov cl,byte ptr hal!HalpIRQLtoTPR
(806ef258)[eax]
806ef2dc 890d8000feff mov dword ptr ds:[0FFFE0080h],ecx
806ef2e2 a18000feff mov eax,dword ptr ds:[FFFE0080h]
806ef2e7 c3 ret

However, the strange thing is, the system called hal!HalpDispatchInterrupt
to handle the DPC before the KeLowerIrq function returned. So, what happed
between the hal!KfLowerIrql and hal!HalpDispatchInterrupt? See below:
ChildEBP RetAddr
f8a05cc0 806efa86 nt!KiDispatchInterrupt
f8a05cc0 806ef2e7 hal!HalpDispatchInterrupt+0xba
f8a05d38 804dd6bc hal!KfLowerIrql+0x17
f8a05d44 804dd6f2 nt!KiSwapThread+0x68
f8a05d6c f814eed2 nt!KeWaitForSingleObject+0x1c2
f8a05dac 8057efed USBPORT!USBPORT_WorkerThread+0x3c
f8a05ddc 804fb477 nt!PspSystemThreadStartup+0x34
00000000 00000000 nt!KiThreadStartup+0x16

On 9/15/06, Peter Wieland wrote:
Since software interrupts only happen because software requested them, it’s
easy enough to record that you wanted to run an interrupt on a particular
CPU somewhere (in the PCR perhaps) and then to have KeLowerIrql check for
that and simulate the interrupt.

I also thought that the APIC could be set to trigger a software interrupt
too, but that’s getting into HAL territory and I know less about the HAL.

-p

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Anders Parker
Sent: Thursday, September 14, 2006 2:05 AM

To: Windows System Software Devs Interest List

Subject: Re: [ntdev] What happened from KfLowerIrql to HalpDispatchInterrupt

Thank Peter for replying. However, there might be some misunderstanding and
maybe that is because I did not describe the problem clearly enough. And I
am sorry for that.
When a hardware interrupt occurs, the CPU is informed by the APIC through
the interrupt line. But there is no such mechanism and no corresponding
interrupt line for software interrupt. How does the CPU know a software
interrupt occurs?
If we queued an IsrForDpc routine during the hardware interrupt processing,
we use the KeLowerIrql function to lower the IRQL from DPC_LEVEL to APC or
PASSIVE LEVEL. But because the KeLowerlrql does not call the
KiDispatchInterrupt function, the problem is, how does the CPU know
immediately that there is a software interrupt waiting for processing?
BTW, I found the following words in the Windows Internal:
The kernel always raises the processor’s IRQL to DPC/dispatch level or above
when it needs to synchronize access to shared kernel structures. This
disables additional software interrupts and thread dispatching .
Since KeRaiseIrql does not modify APIC and just sets the corresponding parts
of PCR, how does the OS mask the hardware interrupt?
— Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256 To unsubscribe, visit the List
Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

“Anders Parker” wrote in message news:xxxxx@ntdev…
> As far as I know, when the DIRQL handles hardware interrupts, driver usually
> calls KeInsertQueueDpc to enqueue an IsrForDpc routine and then requests a
> software interrupt of DPC LEVEL through the hal!HalRequestSoftwareInterrupt
> function.

No, you just call KeInsertQueueDpc and your DPC will be called.
You never need to call HalRequestSoftwareInterrupt directly, Windows
is not Linux.

–PA

> No, you just call KeInsertQueueDpc and your DPC will be called.

You never need to call HalRequestSoftwareInterrupt directly, Windows
is not Linux.

Am I wrong that in Linux, the analog of DPCs is called “bottom halves”, and
they are scheduled by mark_bh()?

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

Jake Oshins wrote:

This instruction:

806ef2d6 8a8858f26e80 mov cl,byte ptr hal!HalpIRQLtoTPR
(806ef258)[eax]

touched the APIC. It lowered the interrupt task priority register, which
unmasked the pending self-interrupt.

That’s a fetch, not a store. I’m guessing that’s just a table lookup
that translates the IRQL value to a TPR priority, and that it is the
next instruction that actually shoves that value into the hardware:

806ef2dc 890d8000feff mov dword ptr ds:[0FFFE0080h],ecx

However, I admit to ignorance about the exact workings of the APIC.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.