29 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
31 #include <linux/kvm_host.h>
32 #include <linux/kvm.h>
34 #include <linux/highmem.h>
35 #include <linux/smp.h>
36 #include <linux/hrtimer.h>
38 #include <linux/slab.h>
39 #include <linux/export.h>
40 #include <linux/nospec.h>
41 #include <asm/processor.h>
43 #include <asm/current.h>
44 #include <trace/events/kvm.h>
60 unsigned long result = 0;
70 result = ((ioapic->
id & 0xf) << 24);
75 u32 redir_index = (ioapic->
ioregsel - 0x10) >> 1;
76 u64 redir_content = ~0ULL;
79 u32 index = array_index_nospec(
86 (redir_content >> 32) & 0xffffffff :
87 redir_content & 0xffffffff;
111 bool new_val, old_val;
123 old_val = test_bit(vcpu->vcpu_id,
dest_map->map);
125 if (new_val == old_val)
129 __set_bit(vcpu->vcpu_id,
dest_map->map);
133 __clear_bit(vcpu->vcpu_id,
dest_map->map);
143 spin_lock(&ioapic->
lock);
145 spin_unlock(&ioapic->
lock);
150 struct kvm_vcpu *vcpu;
157 kvm_for_each_vcpu(i, vcpu, ioapic->
kvm)
167 if (test_bit(vcpu->vcpu_id,
dest_map->map) &&
169 (test_and_clear_bit(vcpu->vcpu_id,
187 struct kvm_vcpu *vcpu;
190 kvm_for_each_vcpu(i, vcpu, ioapic->
kvm) {
207 int irq_level,
bool line_status)
243 if (irq ==
RTC_GSI && line_status &&
249 old_irr = ioapic->
irr;
253 if (old_irr == ioapic->
irr) {
262 trace_kvm_ioapic_set_irq(entry.
bits, irq, ret == 0);
285 spin_lock(&ioapic->
lock);
288 if (test_bit(vcpu->vcpu_id,
dest_map->map))
290 ioapic_handled_vectors);
295 kvm_irq_has_notifier(ioapic->
kvm, KVM_IRQCHIP_IOAPIC, index) ||
303 ioapic_handled_vectors);
306 spin_unlock(&ioapic->
lock);
319 bool mask_before, mask_after;
321 int old_remote_irr, old_delivery_status, old_dest_id, old_dest_mode;
330 ioapic->
id = (val >> 24) & 0xf;
337 index = (ioapic->
ioregsel - 0x10) >> 1;
350 e->
bits &= 0xffffffff;
351 e->
bits |= (u64) val << 32;
353 e->
bits &= ~0xffffffffULL;
354 e->
bits |= (u32) val;
369 if (mask_before != mask_after)
399 if (kvm_notify_irqfd_resampler(ioapic->
kvm, KVM_IRQCHIP_IOAPIC, index))
400 ioapic->
irr &= ~(1 << index);
405 struct kvm_lapic_irq irq;
415 irq.msi_redir_hint =
false;
416 bitmap_zero(vcpu_bitmap, KVM_MAX_VCPUS);
426 irq.dest_id = old_dest_id;
428 kvm_lapic_irq_dest_mode(
445 struct kvm_lapic_irq irqe;
460 irqe.msi_redir_hint =
false;
465 if (irq ==
RTC_GSI && line_status) {
486 int level,
bool line_status)
492 spin_lock(&ioapic->
lock);
493 irq_level = __kvm_irq_line_state(&ioapic->
irq_states[irq],
494 irq_source_id, level);
497 spin_unlock(&ioapic->
lock);
506 spin_lock(&ioapic->
lock);
507 for (i = 0; i < KVM_IOAPIC_NUM_PINS; i++)
508 __clear_bit(irq_source_id, &ioapic->
irq_states[i]);
509 spin_unlock(&ioapic->
lock);
517 spin_lock(&ioapic->
lock);
527 spin_unlock(&ioapic->
lock);
530 #define IOAPIC_SUCCESSIVE_IRQ_MAX_COUNT 10000
547 spin_unlock(&ioapic->
lock);
548 kvm_notify_acked_irq(ioapic->
kvm, KVM_IRQCHIP_IOAPIC, pin);
549 spin_lock(&ioapic->
lock);
568 schedule_delayed_work(&ioapic->
eoi_inject, HZ / 100);
570 trace_kvm_ioapic_delayed_eoi_inj(ent->
bits);
584 spin_lock(&ioapic->
lock);
593 spin_unlock(&ioapic->
lock);
608 gpa_t addr,
int len,
void *val)
618 spin_lock(&ioapic->
lock);
632 spin_unlock(&ioapic->
lock);
636 *(u64 *) val = result;
641 memcpy(val, (
char *)&result, len);
644 printk(KERN_WARNING
"ioapic: wrong length %d\n", len);
650 gpa_t addr,
int len,
const void *val)
671 printk(KERN_WARNING
"ioapic: Unsupported size %d\n", len);
676 spin_lock(&ioapic->
lock);
689 spin_unlock(&ioapic->
lock);
697 cancel_delayed_work_sync(&ioapic->
eoi_inject);
719 ioapic = kzalloc(
sizeof(
struct kvm_ioapic), GFP_KERNEL_ACCOUNT);
722 spin_lock_init(&ioapic->
lock);
724 kvm->arch.vioapic = ioapic;
728 mutex_lock(&
kvm->slots_lock);
731 mutex_unlock(&
kvm->slots_lock);
733 kvm->arch.vioapic = NULL;
747 cancel_delayed_work_sync(&ioapic->
eoi_inject);
748 mutex_lock(&
kvm->slots_lock);
750 mutex_unlock(&
kvm->slots_lock);
751 kvm->arch.vioapic = NULL;
759 spin_lock(&ioapic->
lock);
760 memcpy(
state, ioapic,
sizeof(
struct kvm_ioapic_state));
762 spin_unlock(&ioapic->
lock);
769 spin_lock(&ioapic->
lock);
770 memcpy(ioapic,
state,
sizeof(
struct kvm_ioapic_state));
775 spin_unlock(&ioapic->
lock);
static void kvm_ioapic_eoi_inject_work(struct work_struct *work)
static bool rtc_irq_check_coalesced(struct kvm_ioapic *ioapic)
static void rtc_status_pending_eoi_check_valid(struct kvm_ioapic *ioapic)
void kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state)
int kvm_ioapic_init(struct kvm *kvm)
static void kvm_ioapic_reset(struct kvm_ioapic *ioapic)
static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic)
static void ioapic_lazy_update_eoi(struct kvm_ioapic *ioapic, int irq)
void kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state)
static void rtc_irq_eoi_tracking_reset(struct kvm_ioapic *ioapic)
int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int irq_source_id, int level, bool line_status)
void kvm_arch_post_irq_ack_notifier_list_update(struct kvm *kvm)
static void kvm_rtc_eoi_tracking_restore_all(struct kvm_ioapic *ioapic)
void kvm_rtc_eoi_tracking_restore_one(struct kvm_vcpu *vcpu)
static int ioapic_service(struct kvm_ioapic *vioapic, int irq, bool line_status)
static int ioapic_mmio_read(struct kvm_vcpu *vcpu, struct kvm_io_device *this, gpa_t addr, int len, void *val)
static int ioapic_set_irq(struct kvm_ioapic *ioapic, unsigned int irq, int irq_level, bool line_status)
void kvm_ioapic_update_eoi(struct kvm_vcpu *vcpu, int vector, int trigger_mode)
static struct kvm_ioapic * to_ioapic(struct kvm_io_device *dev)
static int ioapic_mmio_write(struct kvm_vcpu *vcpu, struct kvm_io_device *this, gpa_t addr, int len, const void *val)
static void rtc_irq_eoi(struct kvm_ioapic *ioapic, struct kvm_vcpu *vcpu, int vector)
static void kvm_ioapic_update_eoi_one(struct kvm_vcpu *vcpu, struct kvm_ioapic *ioapic, int trigger_mode, int pin)
static void kvm_ioapic_inject_all(struct kvm_ioapic *ioapic, unsigned long irr)
static int ioapic_in_range(struct kvm_ioapic *ioapic, gpa_t addr)
static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val)
static void __rtc_irq_eoi_tracking_restore_one(struct kvm_vcpu *vcpu)
void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, ulong *ioapic_handled_vectors)
static const struct kvm_io_device_ops ioapic_mmio_ops
void kvm_ioapic_destroy(struct kvm *kvm)
#define IOAPIC_SUCCESSIVE_IRQ_MAX_COUNT
void kvm_ioapic_clear_all(struct kvm_ioapic *ioapic, int irq_source_id)
#define IOAPIC_VERSION_ID
#define IOAPIC_REG_APIC_ID
#define IOAPIC_LEVEL_TRIG
#define IOAPIC_REG_WINDOW
#define IOAPIC_MEM_LENGTH
#define IOAPIC_DEFAULT_BASE_ADDRESS
static int ioapic_in_kernel(struct kvm *kvm)
#define IOAPIC_REG_VERSION
#define IOAPIC_REG_ARB_ID
#define IOAPIC_REG_SELECT
static void kvm_iodevice_init(struct kvm_io_device *dev, const struct kvm_io_device_ops *ops)
int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, struct kvm_lapic_irq *irq, struct dest_map *dest_map)
void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin, bool mask)
int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr, int len, struct kvm_io_device *dev)
int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx, struct kvm_io_device *dev)
void kvm_bitmap_or_dest_vcpus(struct kvm *kvm, struct kvm_lapic_irq *irq, unsigned long *vcpu_bitmap)
bool kvm_apic_pending_eoi(struct kvm_vcpu *vcpu, int vector)
bool kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, int shorthand, unsigned int dest, int dest_mode)
static u32 kvm_lapic_get_reg(struct kvm_lapic *apic, int reg_off)
#define APIC_DEST_NOSHORT
u8 vectors[KVM_MAX_VCPU_IDS]
int(* read)(struct kvm_vcpu *vcpu, struct kvm_io_device *this, gpa_t addr, int len, void *val)
struct delayed_work eoi_inject
struct rtc_status rtc_status
union kvm_ioapic_redirect_entry redirtbl[IOAPIC_NUM_PINS]
unsigned long irq_states[IOAPIC_NUM_PINS]
u32 irq_eoi[IOAPIC_NUM_PINS]
struct kvm_ioapic_redirect_entry::@1 fields
static DECLARE_BITMAP(vmx_vpid_bitmap, VMX_NR_VPIDS)
bool kvm_apicv_activated(struct kvm *kvm)
void kvm_make_scan_ioapic_request_mask(struct kvm *kvm, unsigned long *vcpu_bitmap)
void kvm_make_scan_ioapic_request(struct kvm *kvm)