^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * irq.h: in kernel interrupt controller related definitions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2007, Intel Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Authors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Yaozu (Eddie) Dong <Eddie.dong@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #ifndef __IRQ_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #define __IRQ_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/mm_types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/hrtimer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/kvm_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <kvm/iodev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "lapic.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define PIC_NUM_PINS 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define SELECT_PIC(irq) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) ((irq) < 8 ? KVM_IRQCHIP_PIC_MASTER : KVM_IRQCHIP_PIC_SLAVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) struct kvm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) struct kvm_vcpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct kvm_kpic_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) u8 last_irr; /* edge detection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) u8 irr; /* interrupt request register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) u8 imr; /* interrupt mask register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) u8 isr; /* interrupt service register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) u8 priority_add; /* highest irq priority */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) u8 irq_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) u8 read_reg_select;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) u8 poll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) u8 special_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) u8 init_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) u8 auto_eoi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) u8 rotate_on_auto_eoi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) u8 special_fully_nested_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) u8 init4; /* true if 4 byte init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) u8 elcr; /* PIIX edge/trigger selection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) u8 elcr_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) u8 isr_ack; /* interrupt ack detection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct kvm_pic *pics_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct kvm_pic {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) bool wakeup_needed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) unsigned pending_acks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct kvm *kvm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct kvm_kpic_state pics[2]; /* 0 is master pic, 1 is slave pic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) int output; /* intr from master PIC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct kvm_io_device dev_master;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct kvm_io_device dev_slave;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct kvm_io_device dev_eclr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) void (*ack_notifier)(void *opaque, int irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) unsigned long irq_states[PIC_NUM_PINS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) int kvm_pic_init(struct kvm *kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) void kvm_pic_destroy(struct kvm *kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) int kvm_pic_read_irq(struct kvm *kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) void kvm_pic_update_irq(struct kvm_pic *s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) static inline int irqchip_split(struct kvm *kvm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) int mode = kvm->arch.irqchip_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /* Matches smp_wmb() when setting irqchip_mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) smp_rmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return mode == KVM_IRQCHIP_SPLIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static inline int irqchip_kernel(struct kvm *kvm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) int mode = kvm->arch.irqchip_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /* Matches smp_wmb() when setting irqchip_mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) smp_rmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) return mode == KVM_IRQCHIP_KERNEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) static inline int pic_in_kernel(struct kvm *kvm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return irqchip_kernel(kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static inline int irqchip_in_kernel(struct kvm *kvm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) int mode = kvm->arch.irqchip_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) /* Matches smp_wmb() when setting irqchip_mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) smp_rmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return mode != KVM_IRQCHIP_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) void kvm_apic_nmi_wd_deliver(struct kvm_vcpu *vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) void __kvm_migrate_apic_timer(struct kvm_vcpu *vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) void __kvm_migrate_timers(struct kvm_vcpu *vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) int apic_has_pending_timer(struct kvm_vcpu *vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) int kvm_setup_default_irq_routing(struct kvm *kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) int kvm_setup_empty_irq_routing(struct kvm *kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) struct kvm_lapic_irq *irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct dest_map *dest_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #endif