iT邦幫忙

2025 iThome 鐵人賽

DAY 6
0
自我挑戰組

30 天 hypervisor 入門系列 第 6

Day 06 中斷事件

  • 分享至 

  • xImage
  •  

中斷

在真實的硬體,外部的中段會由中斷控制如 (PIC/APIC)觸發,而 CPU 接受到中斷請求後將會根據暫存器的配置,查找該引腳對應的中斷向量號,並調轉到目標處理函式。
在 KVM 中,為了讓 Guest 能接收外部中斷,我們可以透過 KVM 建立一組虛擬中斷控制器,然後從 Host 端「拉高/拉低」某條中斷線以觸發中斷事件。

Creates an interrupt controller model in the kernel. On x86, creates a virtual ioapic, a virtual PIC (two PICs, nested), and sets up future vcpus to have a local APIC.
文字擷取自 The Definitive KVM (Kernel-based Virtual Machine) API Documentation

模擬中斷控制器:

透過 KVM_CREATE_IRQCHIP,KVM 就把「中斷硬體」幫我們接上。
KVM_IRQ_LINE:同步控制引腳電平(1=assert,0=deassert),用來模擬 edge/level。
KVM_IRQFD:把一個 eventfd 綁到 GSI,寫入 eventfd 即觸發中斷(今天先不展開)

struct irq_manager {
    int vmfd;
    int irqchip_ready;
};

static int create_irqchip(struct irq_manager *mgr)
{
    if (!mgr) {
        errno = EINVAL;
        return -1;
    }
    if (mgr->irqchip_ready) {
        return 0;
    }
    if (ioctl(mgr->vmfd, KVM_CREATE_IRQCHIP, 0) < 0) {
        if (errno == EEXIST) {
            mgr->irqchip_ready = 1;
            return 0;
        }
        return -1;
    }
    mgr->irqchip_ready = 1;
    return 0;
}

int irq_manager_init(struct irq_manager *mgr, int vmfd)
{
    if (!mgr || vmfd < 0) {
        errno = EINVAL;
        return -1;
    }
    memset(mgr, 0, sizeof(*mgr));
    mgr->vmfd = vmfd;
    if (create_irqchip(mgr) < 0) {
        return -1;
    }
    return 0;
}

在這裡抽象了一個 irq_manager 用於管理 irq 相關的事件。這個結構體 struct
irq_manager 將記錄此 VM 的檔案描述符以及是否建立 irqchip 。而 irq_manager_init 將調用 create_irqchip 建立中斷控制器。
需要注意的是當建立中斷控制器後 HLT 將不會觸發 VM-exit (KVM_EXIT_HLT),這是因為 HLT 是讓 CPU 進入低功耗模式同時等待中斷喚醒。


上一篇
Day 05 設計簡易的 VM-exit 處理表
下一篇
Day07 Real Mode 中斷與 IRQ 測試
系列文
30 天 hypervisor 入門11
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言