Page 1 of 1

Generate a MSI interrupt using memory write

Posted: Wed Feb 08, 2012 4:00 am
by u9012063
Hey folks,

AFAIK, the MSI/MSI-X allows device to generate an interrupt by writing the message data to an address. Instead of using device, is it possible to generate a fake interrupt by CPU doing a memory write to the same address with the assigned data?

My experiment:
I have a NIC card with the msi address:feeff00c and data: 41a2. So I wrote a kernel module mapping the physical address feeff00c to a virtual address and call iowrite32(virt_addr, 0x41a2) in order to generate an interrupt. From my understanding, this msi address is actually mapped to the CPU local apic and I assume a memory write to it will generate an interrupt to the cpu. I assume if it works, I can see a interrupt is generated from /proc/interrupts. However, no interrupt has been seen. Is calling iowrite(addr, data) to the msi addr the same as device doing the same thing? Otherwise why didn't I see any interrupt using CPU memory write?

My device information:
00:19.0 Ethernet controller: Intel Corporation 82579LM Gigabit Network Connection (rev 05)
Capabilities: [90] MSI: Enable+ Count=1/1 Maskable- 64bit-
Address: feeff00c Data: 41a2

My /proc/iomem
fee00000-fee00fff : Local APIC
ff000000-ffffffff : reserved

Thanks a lot!

--- William

Re: Generate a MSI interrupt using memory write

Posted: Wed Feb 08, 2012 1:52 pm
by Nable
MSI "address" isn't just an address, it contains some bits with settings. Read more docs about local APIC. And "data" isn't simple data.
Just read `Intel Architecture Software Developer’s Manual, Volume 3A System Programming Guide', chapter 10.11, it's very simple but required to understand MSIs.

And one more thing: don't read/write IO locations directly unless you fully understand what you're doing. It can lead to data loss and/or even hardware damage. Yes, really. (-;

Re: Generate a MSI interrupt using memory write

Posted: Wed Feb 08, 2012 6:54 pm
by u9012063
Thanks! I've checked my address: 0xfee0100c and data: 41a2

From the IA32 manual:
The address register = 0xfee0100c goes like this:
Bits 31 to 20 = 0xFEE = address is in the local APIC area
Bits 19 to 12 = Destination APIC ID for the IRQ = 1
Bit 3 = RH = Redirection Hint = 1
Bit 2 = DM = Destination Mode (same meaning as for IPIs) = 1
Bits 0 to 1 = Don't care
In my case, RH = DM = 1, From the IA32, "If RH is 1 and DM is 1, the Destination ID Field is interpreted as in logical destination mode and the redirection is limited to only those processors that are part of the logical group of processors based on the processor’s logical APIC ID and the Destination ID field in the message."
How do I know my processor's APIC ID and which redirection mode is used in the current configuration?

The data register = 41aa, goes like this:
Bit 15 = Trigger Mode (edge or level triggered) = 0 edge trigger
Bit 14 = polarity = 1: Assert
Bits 8 to 10 = Delivery mode = 1 = Lowest Priority
Bits 0 to 7 = Interrupt vector = aa
(Lowest Priority) — Deliver the signal to the agent that is executing at the lowest priority of all agents listed in the destination field. The trigger mode can be edge or level.


Regards,
William

Re: Generate a MSI interrupt using memory write

Posted: Wed Feb 08, 2012 10:23 pm
by Brendan
Hi,
u9012063 wrote:AFAIK, the MSI/MSI-X allows device to generate an interrupt by writing the message data to an address. Instead of using device, is it possible to generate a fake interrupt by CPU doing a memory write to the same address with the assigned data?
No.

Writes from the CPU to it's own (internal) local APIC area aren't visible outside that CPU (the CPU handles the writes internally itself). Writes from the bus to the MSI area are intercepted by the chipset or memory controller and converted into "interrupt messages" before any CPU sees them (the CPU only sees the "interrupt messages" and doesn't see writes to the MSI area).

If you want to send an interrupt from one CPU to another (or from one CPU to itself, or from one CPU to a group of CPUs), then use the local APIC to send an IPI (Inter-Processor Interrupt)).


Cheers,

Brendan

Re: Generate a MSI interrupt using memory write

Posted: Tue Feb 14, 2012 5:36 am
by u9012063
Hi Brendan,
Thanks a lot~ very appreciate
William