4

I'm trying to play around with the local APIC functions in the 2.6.32.40 linux kernel, but I am having some issues. I want to try to send a Non-Maskable Interrupts (NMI) to all of the processors on my system (I am using a Intel i7 Q740). First I read the documentation in Intel's Software Developer's Manual Volume 3 related to the APIC functions. It states that interrupts can be broadcast to all processors through the use of the Interrupt Command Register (ICR) located at address 0xFEE00300. So I wrote a kernel module with the following init function to try to write to this register:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>

MODULE_LICENSE("GPL");

#define SUCCESS 0
#define ICR_ADDRESS 0xFEE00300
#define ICR_PROGRAM 0x000C4C89

static int icr_init(void){

    int * ICR = (int *)ICR_ADDRESS;

    printk(KERN_ALERT "Programing ICR\n");

    *ICR = ICR_PROGRAM;

    return SUCCESS;
}

static void icr_exit(void){
    printk(KERN_ALERT "Removing ICR Programing module removed");
}

module_init(icr_init);
module_exit(icr_exit);

However, when I insmod this module the kernel crashes and complains about being unable to handle the paging request @ address 00000000fee00300. Looking under /proc/iomem I see that this address is in a ranged marked as "reserved"

fee00000-fee00fff : reserved

I've also tried using the functions under :

static inline void __default_local_send_IPI_allbutself(int vector)

but the kernel is still throwing "unable to handle paging request" messages and crashing. Does anyone have any suggestions? Why is this memory range marked as "reserved" and not marked as being used by the local APIC? Thanks in advance.

John
  • 61
  • 5

1 Answers1

3

The APIC address is a physical memory address, but you are trying to access it as a linear memory address - that's why your first approach doesn't work. The memory is marked as "reserved" precisely because it belongs to the APIC, rather than real memory.

You should use the internal kernel functions. To do so, you should include <asm/apic.h> and use:

apic->send_IPI_allbutself(vector);
caf
  • 233,326
  • 40
  • 323
  • 462
  • I'm having the same issue with this function as I am with: static inline void __default_local_send_IPI_allbutself(int vector) I get kernel message: BUG: unable to handle kernel paging request at FFFFFFFFFF5fb300 – John Aug 11 '11 at 21:29
  • Actually, I've resolved the issue. The problem arose from lack of information on my part. I was running this code in domain0 of a Xen hypervisor. Xen was blocking the writes to system memory (dumb mistake on my part). – John Aug 11 '11 at 21:52
  • 1
    @John: Your first approach would still have failed on the bare metal. – caf Aug 11 '11 at 22:15