Помогите с функциями APIC в Linux - PullRequest
4 голосов
/ 08 августа 2011

Я пытаюсь поиграться с локальными функциями APIC в ядре Linux 2.6.32.40, но у меня возникли некоторые проблемы. Я хочу попробовать отправить немаскируемые прерывания (NMI) на все процессоры в моей системе (я использую Intel i7 Q740). Сначала я прочитал документацию в Руководстве Intel для разработчиков ПО, том 3, касающуюся функций APIC. В нем говорится, что прерывания могут передаваться всем процессорам посредством использования регистра команд прерываний (ICR), расположенного по адресу 0xFEE00300. Поэтому я написал модуль ядра со следующей функцией init, чтобы попытаться записать в этот регистр:

#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);

Однако, когда я инсталлирую этот модуль, ядро ​​вылетает и жалуется, что не может обработать запрос подкачки @ address 00000000fee00300. Глядя в / proc / iomem, я вижу, что этот адрес находится в диапазоне, помеченном как «зарезервированный»

fee00000-fee00fff : reserved

Я также пытался использовать функции в:

static inline void __default_local_send_IPI_allbutself(int vector)

но ядро ​​все еще выдаёт сообщения "не в состоянии обработать запрос пейджинга" и вылетает. У кого-нибудь есть предложения? Почему этот диапазон памяти помечен как «зарезервированный» и не помечен как используемый локальным APIC? Заранее спасибо.

1 Ответ

3 голосов
/ 11 августа 2011

Адрес APIC - это адрес физической памяти, но вы пытаетесь получить к нему доступ как линейный адрес памяти - вот почему ваш первый подход не работает. Память помечена как «зарезервированная» точно , поскольку принадлежит APIC, а не реальной памяти.

Вы должны использовать внутренние функции ядра. Для этого вы должны включить <asm/apic.h> и использовать:

apic->send_IPI_allbutself(vector);
...