^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Copyright (C) 2001 MandrakeSoft S.A.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright 2010 Red Hat, Inc. and/or its affiliates.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * MandrakeSoft S.A.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * 43, rue d'Aboukir
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * 75002 Paris - France
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * http://www.linux-mandrake.com/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * http://www.mandrakesoft.com/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * This library is free software; you can redistribute it and/or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * modify it under the terms of the GNU Lesser General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * License as published by the Free Software Foundation; either
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * version 2 of the License, or (at your option) any later version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * This library is distributed in the hope that it will be useful,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * but WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * Lesser General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * You should have received a copy of the GNU Lesser General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * License along with this library; if not, write to the Free Software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * Yunhong Jiang <yunhong.jiang@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * Yaozu (Eddie) Dong <eddie.dong@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * Based on Xen 3.1 code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/kvm_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/kvm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/highmem.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/hrtimer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/nospec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <asm/processor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <asm/page.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <asm/current.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <trace/events/kvm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include "ioapic.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include "lapic.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include "irq.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static int ioapic_service(struct kvm_ioapic *vioapic, int irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) bool line_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static void kvm_ioapic_update_eoi_one(struct kvm_vcpu *vcpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct kvm_ioapic *ioapic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) int trigger_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) int pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) unsigned long addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) unsigned long length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) unsigned long result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) switch (ioapic->ioregsel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) case IOAPIC_REG_VERSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) result = ((((IOAPIC_NUM_PINS - 1) & 0xff) << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) | (IOAPIC_VERSION_ID & 0xff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) case IOAPIC_REG_APIC_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) case IOAPIC_REG_ARB_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) result = ((ioapic->id & 0xf) << 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) u32 redir_index = (ioapic->ioregsel - 0x10) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) u64 redir_content = ~0ULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (redir_index < IOAPIC_NUM_PINS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) u32 index = array_index_nospec(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) redir_index, IOAPIC_NUM_PINS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) redir_content = ioapic->redirtbl[index].bits;
^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) result = (ioapic->ioregsel & 0x1) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) (redir_content >> 32) & 0xffffffff :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) redir_content & 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static void rtc_irq_eoi_tracking_reset(struct kvm_ioapic *ioapic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) ioapic->rtc_status.pending_eoi = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) bitmap_zero(ioapic->rtc_status.dest_map.map, KVM_MAX_VCPU_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static void kvm_rtc_eoi_tracking_restore_all(struct kvm_ioapic *ioapic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static void rtc_status_pending_eoi_check_valid(struct kvm_ioapic *ioapic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (WARN_ON(ioapic->rtc_status.pending_eoi < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) kvm_rtc_eoi_tracking_restore_all(ioapic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static void __rtc_irq_eoi_tracking_restore_one(struct kvm_vcpu *vcpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) bool new_val, old_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct kvm_ioapic *ioapic = vcpu->kvm->arch.vioapic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct dest_map *dest_map = &ioapic->rtc_status.dest_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) union kvm_ioapic_redirect_entry *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) e = &ioapic->redirtbl[RTC_GSI];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (!kvm_apic_match_dest(vcpu, NULL, APIC_DEST_NOSHORT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) e->fields.dest_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) kvm_lapic_irq_dest_mode(!!e->fields.dest_mode)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) new_val = kvm_apic_pending_eoi(vcpu, e->fields.vector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) old_val = test_bit(vcpu->vcpu_id, dest_map->map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (new_val == old_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if (new_val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) __set_bit(vcpu->vcpu_id, dest_map->map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) dest_map->vectors[vcpu->vcpu_id] = e->fields.vector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) ioapic->rtc_status.pending_eoi++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) __clear_bit(vcpu->vcpu_id, dest_map->map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) ioapic->rtc_status.pending_eoi--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) rtc_status_pending_eoi_check_valid(ioapic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) void kvm_rtc_eoi_tracking_restore_one(struct kvm_vcpu *vcpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct kvm_ioapic *ioapic = vcpu->kvm->arch.vioapic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) spin_lock(&ioapic->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) __rtc_irq_eoi_tracking_restore_one(vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) spin_unlock(&ioapic->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) static void kvm_rtc_eoi_tracking_restore_all(struct kvm_ioapic *ioapic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) struct kvm_vcpu *vcpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (RTC_GSI >= IOAPIC_NUM_PINS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) rtc_irq_eoi_tracking_reset(ioapic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) kvm_for_each_vcpu(i, vcpu, ioapic->kvm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) __rtc_irq_eoi_tracking_restore_one(vcpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static void rtc_irq_eoi(struct kvm_ioapic *ioapic, struct kvm_vcpu *vcpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) int vector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) struct dest_map *dest_map = &ioapic->rtc_status.dest_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /* RTC special handling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) if (test_bit(vcpu->vcpu_id, dest_map->map) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) (vector == dest_map->vectors[vcpu->vcpu_id]) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) (test_and_clear_bit(vcpu->vcpu_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) ioapic->rtc_status.dest_map.map))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) --ioapic->rtc_status.pending_eoi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) rtc_status_pending_eoi_check_valid(ioapic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static bool rtc_irq_check_coalesced(struct kvm_ioapic *ioapic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (ioapic->rtc_status.pending_eoi > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) return true; /* coalesced */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static void ioapic_lazy_update_eoi(struct kvm_ioapic *ioapic, int irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) struct kvm_vcpu *vcpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) union kvm_ioapic_redirect_entry *entry = &ioapic->redirtbl[irq];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) kvm_for_each_vcpu(i, vcpu, ioapic->kvm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (!kvm_apic_match_dest(vcpu, NULL, APIC_DEST_NOSHORT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) entry->fields.dest_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) entry->fields.dest_mode) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) kvm_apic_pending_eoi(vcpu, entry->fields.vector))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * If no longer has pending EOI in LAPICs, update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * EOI for this vector.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) rtc_irq_eoi(ioapic, vcpu, entry->fields.vector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) static int ioapic_set_irq(struct kvm_ioapic *ioapic, unsigned int irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) int irq_level, bool line_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) union kvm_ioapic_redirect_entry entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) u32 mask = 1 << irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) u32 old_irr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) int edge, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) entry = ioapic->redirtbl[irq];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) edge = (entry.fields.trig_mode == IOAPIC_EDGE_TRIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (!irq_level) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) ioapic->irr &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * AMD SVM AVIC accelerate EOI write iff the interrupt is edge
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * triggered, in which case the in-kernel IOAPIC will not be able
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * to receive the EOI. In this case, we do a lazy update of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * pending EOI when trying to set IOAPIC irq.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (edge && kvm_apicv_activated(ioapic->kvm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) ioapic_lazy_update_eoi(ioapic, irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * Return 0 for coalesced interrupts; for edge-triggered interrupts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * this only happens if a previous edge has not been delivered due
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * to masking. For level interrupts, the remote_irr field tells
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * us if the interrupt is waiting for an EOI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * RTC is special: it is edge-triggered, but userspace likes to know
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * if it has been already ack-ed via EOI because coalesced RTC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * interrupts lead to time drift in Windows guests. So we track
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * EOI manually for the RTC interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (irq == RTC_GSI && line_status &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) rtc_irq_check_coalesced(ioapic)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) old_irr = ioapic->irr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) ioapic->irr |= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (edge) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) ioapic->irr_delivered &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (old_irr == ioapic->irr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) ret = ioapic_service(ioapic, irq, line_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) trace_kvm_ioapic_set_irq(entry.bits, irq, ret == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) static void kvm_ioapic_inject_all(struct kvm_ioapic *ioapic, unsigned long irr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) u32 idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) rtc_irq_eoi_tracking_reset(ioapic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) for_each_set_bit(idx, &irr, IOAPIC_NUM_PINS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) ioapic_set_irq(ioapic, idx, 1, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) kvm_rtc_eoi_tracking_restore_all(ioapic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, ulong *ioapic_handled_vectors)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct kvm_ioapic *ioapic = vcpu->kvm->arch.vioapic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) struct dest_map *dest_map = &ioapic->rtc_status.dest_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) union kvm_ioapic_redirect_entry *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) spin_lock(&ioapic->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) /* Make sure we see any missing RTC EOI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if (test_bit(vcpu->vcpu_id, dest_map->map))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) __set_bit(dest_map->vectors[vcpu->vcpu_id],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) ioapic_handled_vectors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) for (index = 0; index < IOAPIC_NUM_PINS; index++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) e = &ioapic->redirtbl[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (e->fields.trig_mode == IOAPIC_LEVEL_TRIG ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) kvm_irq_has_notifier(ioapic->kvm, KVM_IRQCHIP_IOAPIC, index) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) index == RTC_GSI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) u16 dm = kvm_lapic_irq_dest_mode(!!e->fields.dest_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (kvm_apic_match_dest(vcpu, NULL, APIC_DEST_NOSHORT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) e->fields.dest_id, dm) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) kvm_apic_pending_eoi(vcpu, e->fields.vector))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) __set_bit(e->fields.vector,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) ioapic_handled_vectors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) spin_unlock(&ioapic->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) void kvm_arch_post_irq_ack_notifier_list_update(struct kvm *kvm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (!ioapic_in_kernel(kvm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) kvm_make_scan_ioapic_request(kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) unsigned index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) bool mask_before, mask_after;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) union kvm_ioapic_redirect_entry *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) int old_remote_irr, old_delivery_status, old_dest_id, old_dest_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) DECLARE_BITMAP(vcpu_bitmap, KVM_MAX_VCPUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) switch (ioapic->ioregsel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) case IOAPIC_REG_VERSION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) /* Writes are ignored. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) case IOAPIC_REG_APIC_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) ioapic->id = (val >> 24) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) case IOAPIC_REG_ARB_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) index = (ioapic->ioregsel - 0x10) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) if (index >= IOAPIC_NUM_PINS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) index = array_index_nospec(index, IOAPIC_NUM_PINS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) e = &ioapic->redirtbl[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) mask_before = e->fields.mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) /* Preserve read-only fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) old_remote_irr = e->fields.remote_irr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) old_delivery_status = e->fields.delivery_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) old_dest_id = e->fields.dest_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) old_dest_mode = e->fields.dest_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (ioapic->ioregsel & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) e->bits &= 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) e->bits |= (u64) val << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) e->bits &= ~0xffffffffULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) e->bits |= (u32) val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) e->fields.remote_irr = old_remote_irr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) e->fields.delivery_status = old_delivery_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * Some OSes (Linux, Xen) assume that Remote IRR bit will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) * be cleared by IOAPIC hardware when the entry is configured
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) * as edge-triggered. This behavior is used to simulate an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * explicit EOI on IOAPICs that don't have the EOI register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) if (e->fields.trig_mode == IOAPIC_EDGE_TRIG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) e->fields.remote_irr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) mask_after = e->fields.mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (mask_before != mask_after)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) kvm_fire_mask_notifiers(ioapic->kvm, KVM_IRQCHIP_IOAPIC, index, mask_after);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (e->fields.trig_mode == IOAPIC_LEVEL_TRIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) && ioapic->irr & (1 << index))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) ioapic_service(ioapic, index, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (e->fields.delivery_mode == APIC_DM_FIXED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) struct kvm_lapic_irq irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) irq.vector = e->fields.vector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) irq.delivery_mode = e->fields.delivery_mode << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) irq.dest_mode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) kvm_lapic_irq_dest_mode(!!e->fields.dest_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) irq.level = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) irq.trig_mode = e->fields.trig_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) irq.shorthand = APIC_DEST_NOSHORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) irq.dest_id = e->fields.dest_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) irq.msi_redir_hint = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) bitmap_zero(vcpu_bitmap, KVM_MAX_VCPUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) kvm_bitmap_or_dest_vcpus(ioapic->kvm, &irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) vcpu_bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (old_dest_mode != e->fields.dest_mode ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) old_dest_id != e->fields.dest_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) * Update vcpu_bitmap with vcpus specified in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) * the previous request as well. This is done to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) * keep ioapic_handled_vectors synchronized.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) irq.dest_id = old_dest_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) irq.dest_mode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) kvm_lapic_irq_dest_mode(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) !!e->fields.dest_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) kvm_bitmap_or_dest_vcpus(ioapic->kvm, &irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) vcpu_bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) kvm_make_scan_ioapic_request_mask(ioapic->kvm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) vcpu_bitmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) kvm_make_scan_ioapic_request(ioapic->kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) static int ioapic_service(struct kvm_ioapic *ioapic, int irq, bool line_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) union kvm_ioapic_redirect_entry *entry = &ioapic->redirtbl[irq];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) struct kvm_lapic_irq irqe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (entry->fields.mask ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) (entry->fields.trig_mode == IOAPIC_LEVEL_TRIG &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) entry->fields.remote_irr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) irqe.dest_id = entry->fields.dest_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) irqe.vector = entry->fields.vector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) irqe.dest_mode = kvm_lapic_irq_dest_mode(!!entry->fields.dest_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) irqe.trig_mode = entry->fields.trig_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) irqe.delivery_mode = entry->fields.delivery_mode << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) irqe.level = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) irqe.shorthand = APIC_DEST_NOSHORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) irqe.msi_redir_hint = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) if (irqe.trig_mode == IOAPIC_EDGE_TRIG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) ioapic->irr_delivered |= 1 << irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) if (irq == RTC_GSI && line_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) * pending_eoi cannot ever become negative (see
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) * rtc_status_pending_eoi_check_valid) and the caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) * ensures that it is only called if it is >= zero, namely
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) * if rtc_irq_check_coalesced returns false).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) BUG_ON(ioapic->rtc_status.pending_eoi != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) ret = kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) &ioapic->rtc_status.dest_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) ioapic->rtc_status.pending_eoi = (ret < 0 ? 0 : ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) ret = kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (ret && irqe.trig_mode == IOAPIC_LEVEL_TRIG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) entry->fields.remote_irr = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) int kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int irq_source_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) int level, bool line_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) int ret, irq_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) BUG_ON(irq < 0 || irq >= IOAPIC_NUM_PINS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) spin_lock(&ioapic->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) irq_level = __kvm_irq_line_state(&ioapic->irq_states[irq],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) irq_source_id, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) ret = ioapic_set_irq(ioapic, irq, irq_level, line_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) spin_unlock(&ioapic->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) void kvm_ioapic_clear_all(struct kvm_ioapic *ioapic, int irq_source_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) spin_lock(&ioapic->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) for (i = 0; i < KVM_IOAPIC_NUM_PINS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) __clear_bit(irq_source_id, &ioapic->irq_states[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) spin_unlock(&ioapic->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) static void kvm_ioapic_eoi_inject_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) struct kvm_ioapic *ioapic = container_of(work, struct kvm_ioapic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) eoi_inject.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) spin_lock(&ioapic->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) for (i = 0; i < IOAPIC_NUM_PINS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) union kvm_ioapic_redirect_entry *ent = &ioapic->redirtbl[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (ent->fields.trig_mode != IOAPIC_LEVEL_TRIG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) if (ioapic->irr & (1 << i) && !ent->fields.remote_irr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) ioapic_service(ioapic, i, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) spin_unlock(&ioapic->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) #define IOAPIC_SUCCESSIVE_IRQ_MAX_COUNT 10000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) static void kvm_ioapic_update_eoi_one(struct kvm_vcpu *vcpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) struct kvm_ioapic *ioapic,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) int trigger_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) int pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) struct kvm_lapic *apic = vcpu->arch.apic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) union kvm_ioapic_redirect_entry *ent = &ioapic->redirtbl[pin];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) * We are dropping lock while calling ack notifiers because ack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) * notifier callbacks for assigned devices call into IOAPIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) * recursively. Since remote_irr is cleared only after call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) * to notifiers if the same vector will be delivered while lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) * is dropped it will be put into irr and will be delivered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) * after ack notifier returns.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) spin_unlock(&ioapic->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) kvm_notify_acked_irq(ioapic->kvm, KVM_IRQCHIP_IOAPIC, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) spin_lock(&ioapic->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (trigger_mode != IOAPIC_LEVEL_TRIG ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) kvm_lapic_get_reg(apic, APIC_SPIV) & APIC_SPIV_DIRECTED_EOI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) ASSERT(ent->fields.trig_mode == IOAPIC_LEVEL_TRIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) ent->fields.remote_irr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (!ent->fields.mask && (ioapic->irr & (1 << pin))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) ++ioapic->irq_eoi[pin];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (ioapic->irq_eoi[pin] == IOAPIC_SUCCESSIVE_IRQ_MAX_COUNT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) * Real hardware does not deliver the interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) * immediately during eoi broadcast, and this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) * lets a buggy guest make slow progress
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) * even if it does not correctly handle a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) * level-triggered interrupt. Emulate this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) * behavior if we detect an interrupt storm.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) schedule_delayed_work(&ioapic->eoi_inject, HZ / 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) ioapic->irq_eoi[pin] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) trace_kvm_ioapic_delayed_eoi_inj(ent->bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) ioapic_service(ioapic, pin, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) ioapic->irq_eoi[pin] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) void kvm_ioapic_update_eoi(struct kvm_vcpu *vcpu, int vector, int trigger_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) struct kvm_ioapic *ioapic = vcpu->kvm->arch.vioapic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) spin_lock(&ioapic->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) rtc_irq_eoi(ioapic, vcpu, vector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) for (i = 0; i < IOAPIC_NUM_PINS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) union kvm_ioapic_redirect_entry *ent = &ioapic->redirtbl[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) if (ent->fields.vector != vector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) kvm_ioapic_update_eoi_one(vcpu, ioapic, trigger_mode, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) spin_unlock(&ioapic->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) static inline struct kvm_ioapic *to_ioapic(struct kvm_io_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return container_of(dev, struct kvm_ioapic, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) static inline int ioapic_in_range(struct kvm_ioapic *ioapic, gpa_t addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) return ((addr >= ioapic->base_address &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) (addr < ioapic->base_address + IOAPIC_MEM_LENGTH)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) static int ioapic_mmio_read(struct kvm_vcpu *vcpu, struct kvm_io_device *this,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) gpa_t addr, int len, void *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) struct kvm_ioapic *ioapic = to_ioapic(this);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) u32 result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) if (!ioapic_in_range(ioapic, addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) ASSERT(!(addr & 0xf)); /* check alignment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) addr &= 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) spin_lock(&ioapic->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) switch (addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) case IOAPIC_REG_SELECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) result = ioapic->ioregsel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) case IOAPIC_REG_WINDOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) result = ioapic_read_indirect(ioapic, addr, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) spin_unlock(&ioapic->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) switch (len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) *(u64 *) val = result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) memcpy(val, (char *)&result, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) printk(KERN_WARNING "ioapic: wrong length %d\n", len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) static int ioapic_mmio_write(struct kvm_vcpu *vcpu, struct kvm_io_device *this,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) gpa_t addr, int len, const void *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) struct kvm_ioapic *ioapic = to_ioapic(this);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) u32 data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) if (!ioapic_in_range(ioapic, addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) ASSERT(!(addr & 0xf)); /* check alignment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) switch (len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) data = *(u32 *) val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) data = *(u16 *) val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) data = *(u8 *) val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) printk(KERN_WARNING "ioapic: Unsupported size %d\n", len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) addr &= 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) spin_lock(&ioapic->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) switch (addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) case IOAPIC_REG_SELECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) ioapic->ioregsel = data & 0xFF; /* 8-bit register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) case IOAPIC_REG_WINDOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) ioapic_write_indirect(ioapic, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) spin_unlock(&ioapic->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) static void kvm_ioapic_reset(struct kvm_ioapic *ioapic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) cancel_delayed_work_sync(&ioapic->eoi_inject);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) for (i = 0; i < IOAPIC_NUM_PINS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) ioapic->redirtbl[i].fields.mask = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) ioapic->base_address = IOAPIC_DEFAULT_BASE_ADDRESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) ioapic->ioregsel = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) ioapic->irr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) ioapic->irr_delivered = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) ioapic->id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) memset(ioapic->irq_eoi, 0x00, sizeof(ioapic->irq_eoi));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) rtc_irq_eoi_tracking_reset(ioapic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) static const struct kvm_io_device_ops ioapic_mmio_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) .read = ioapic_mmio_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) .write = ioapic_mmio_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) int kvm_ioapic_init(struct kvm *kvm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) struct kvm_ioapic *ioapic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) ioapic = kzalloc(sizeof(struct kvm_ioapic), GFP_KERNEL_ACCOUNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if (!ioapic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) spin_lock_init(&ioapic->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) INIT_DELAYED_WORK(&ioapic->eoi_inject, kvm_ioapic_eoi_inject_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) kvm->arch.vioapic = ioapic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) kvm_ioapic_reset(ioapic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) kvm_iodevice_init(&ioapic->dev, &ioapic_mmio_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) ioapic->kvm = kvm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) mutex_lock(&kvm->slots_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) ret = kvm_io_bus_register_dev(kvm, KVM_MMIO_BUS, ioapic->base_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) IOAPIC_MEM_LENGTH, &ioapic->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) mutex_unlock(&kvm->slots_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) kvm->arch.vioapic = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) kfree(ioapic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) void kvm_ioapic_destroy(struct kvm *kvm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) struct kvm_ioapic *ioapic = kvm->arch.vioapic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) if (!ioapic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) cancel_delayed_work_sync(&ioapic->eoi_inject);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) mutex_lock(&kvm->slots_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) kvm_io_bus_unregister_dev(kvm, KVM_MMIO_BUS, &ioapic->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) mutex_unlock(&kvm->slots_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) kvm->arch.vioapic = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) kfree(ioapic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) void kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) struct kvm_ioapic *ioapic = kvm->arch.vioapic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) spin_lock(&ioapic->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) memcpy(state, ioapic, sizeof(struct kvm_ioapic_state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) state->irr &= ~ioapic->irr_delivered;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) spin_unlock(&ioapic->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) void kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) struct kvm_ioapic *ioapic = kvm->arch.vioapic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) spin_lock(&ioapic->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) memcpy(ioapic, state, sizeof(struct kvm_ioapic_state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) ioapic->irr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) ioapic->irr_delivered = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) kvm_make_scan_ioapic_request(kvm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) kvm_ioapic_inject_all(ioapic, state->irr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) spin_unlock(&ioapic->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) }