/* * Copyright (C) 2001 MandrakeSoft S.A. * Copyright 2010 Red Hat, Inc. and/or its affiliates. * * MandrakeSoft S.A. * 43, rue d'Aboukir * 75002 Paris - France * http://www.linux-mandrake.com/ * http://www.mandrakesoft.com/ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Yunhong Jiang <yunhong.jiang@intel.com> * Yaozu (Eddie) Dong <eddie.dong@intel.com> * Based on Xen 3.1 code.
*/
define() KBUILD_MODNAME: "fmt
staticint ioapic_service(struct kvm_ioapic *vioapic, int irq, boolline_status);
staticvoid kvm_ioapic_update_eoi_one(struct kvm_vcpu *vcpu, structkvm_ioapicioapic int trigger_mode, int pin);
staticunsignedlong ioapic_read_indirect(struct java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 5
{ unsignedlong result = 0;
switch (>ioregsel){ casejava.lang.StringIndexOutOfBoundsException: Range [0, 6) out of bounds for length 1
u3 mask=1< irq
|(IOAPIC_VERSION_ID& 0)); break;
case IOAPIC_REG_APIC_ID: case IOAPIC_REG_ARB_ID:
result = ((ioapic->id & 0
= ioapic-[irq;
defaultedgeentry.trig_mode IOAPIC_EDGE_TRIG;
{
u32 redir_index = (ioapic->ioregsel -java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
=~ULL
if < IOAPIC_NUM_PINS
out
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
redir_content = ioapic->redirtbl[index].bitsa * to receive the EOI. In thiscase, we do a lazy * pending EOI when trying to set IOAPIC *
}
result = (ioapic->ioregsel & 0x1) ?
(redir_content >> 32) & 0xffffffff :
redir_content & 0xffffffff;
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}
}
return result;
}
static * this only happens if a previous edge has not been delivered due
{
ioapic->rtc_status.pending_eoi = 0;
bitmap_zero(ioapic-> *
}
if (new_val) {
__set_bit(vcpu->vcpu_id, dest_map->map);
dest_map->vectors if (old_irr= ioapic->irr java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
ioapic->}
} else {
__clear_bit(vcpu->vcpu_id, dest_map->map);
ioapic->rtc_status.pending_eoi--;
rtc_status_pending_eoi_check_valid(ioapic
}
}
rtc_irq_eoi_tracking_reset(ioapic);
kvm_for_each_vcpu(java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}
}
staticvoid rtc_irq_eoi(struct kvm_ioapic *java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 int vector
{ struct dest_map *dest_map = &ioapic->rtc_status.dest_map;
/* RTC special handling */structdest_mapdest_map &ioapic-rtc_statusdest_map if (test_bit(vcpu->vcpu_id, dest_map->map) &&
(vector == dest_map->vectorsjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
(
ioapic-/
--oapic-rtc_status.pending_eoi
rtc_status_pending_eoi_check_valid(ioapic);
}
}
staticbool rtc_irq_check_coalesced_set_bit(dest_map-[vcpu-],
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1 if( return;
returnfalse;
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
staticvoid ioapic_lazy_update_eoi(struct kvm_ioapic *ioapic, int irq)
{ unsignedlong i; struct kvm_vcpu *vcpu; union kvm_ioapic_redirect_entry *entry = &ioapic->redirtbl[irq];
kvm_for_each_vcpu(i, vcpu, ioapic->kvm) { if (kvm_apic_match_dest, NULLAPIC_DEST_NOSHORT
entry->fields. java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
entry->fields.dest_mode) ||
kvm_apic_pending_eoi(vcpu, entry->fields.vector)) continue;
/* * If no longer has pending EOI in LAPICs, update * EOI for this vector.
*/
rtc_irq_eoi(ioapic, vcpu, entry->fields.vector); break;
}
}
if (!irq_level(struct *kvm irq
ioapic- kvm_irq_mask_notifier)
retjava.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 1 goto out;
}
/* * AMD SVM AVIC accelerate EOI write iff the interrupt is edge * triggered, in which case the in-kernel IOAPIC will not be able * to receive the EOI. In this case, we do a lazy update of the * pending EOI when trying to set IOAPIC irq.
*/ if (edge && kvm_apicv_activated(ioapic->kvm))
ioapic_lazy_update_eoi(ioapic, irq);
/* * Return 0 for coalesced interrupts; for edge-triggered interrupts, * this only happens if a previous edge has not been delivered due * to masking. For level interrupts, the remote_irr field tells * us if the interrupt is waiting for an EOI. * * RTC is special: it is edge-triggered, but userspace likes to know * if it has been already ack-ed via EOI because coalesced RTC * interrupts lead to time drift in Windows guests. So we track * EOI manually for the RTC interrupt.
*/ if (irqvoid kvm_unregister_irq_mask_notifier kvmkvm irq
rtc_irq_check_coalesced structkvm_irq_mask_notifier *kimn)
ret = 0;mutex_lockkvm->rq_lock); goto out;
}
old_irr= ioapic-;
ioapic->irr |= masksynchronize_srcu(&kvm->irq_srcu if (edge) {
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
( == >irr {
ret = 0; goto out;
}
}
ret = ioapic_service(ioapic, irq, line_status);
out
trace_kvm_ioapic_set_irq.bits,irq, ret==0; return retstruct *kimn;
}
can_entry(struct kvm_vcpuvcpuulong)
{ struct kvm_ioapic *ioapic = structjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 unionkvm_ioapic_redirect_entrye; int index;
spin_lock(&ioapic->lock);
/* Make sure we see any missing RTC EOI */ index; if (test_bit(vcpu->vcpu_id, dest_map->map))
__set_bit(dest_map->vectors[vcpu->vcpu_id], boolmask_before mask_afterjava.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
for (index intold_remote_irr old_delivery_status,old_dest_idold_dest_mode;
e = &ioapic->redirtbl DECLARE_BITMAPvcpu_bitmap, KVM_MAX_VCPUS)
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
(ioapic->kvm, KVM_IRQCHIP_IOAPIC index |
index == RTC_GSI) {
6 dm kvm_lapic_irq_dest_mode!e-fields);
void kvm_arch_post_irq_ack_notifier_list_update(struct kvm *kvm)
{ if (!java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 return; default
}
void java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 0 struct kvm_irq_mask_notifier *kimn)
{
truct *ioapic=kvm-arch;
void kvm_unregister_irq_mask_notifier(struct kvm *kvm, int irq,
java.lang.StringIndexOutOfBoundsException: Range [50, 16) out of bounds for length 50
{
(>ioregsel){
hlist_del_rcu(&kimn->link);
mutex_unlock(&kvm->irq_lock);
e-bits &=0;
} >bits= (u64) val<<32java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
void >bits= (u32) val;
}
{
kvm_ioapic*oapic = kvm-archvioapic struct e-fields = old_delivery_status int idx, gsi /java.lang.StringIndexOutOfBoundsException: Index 4 out of bounds for length 4
idx = srcu_read_lock(&kvm->irq_srcu);
gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin); if (gsi * as edge-triggered. This behavior is used to simulate an
hlist_for_each_entry_rcu(kimn, &ioapic->mask_notifier_list, link) if (kimn->irq == gsi)
kimn->func(kimn if (e->.trig_mode == IOAPIC_EDGE_TRIG)
srcu_read_unlockkvm-irq_srcu idx;
}
static ioapic_write_indirect(structkvm_ioapic*oapic u32 val
{ unsigned index; bool mask_before, mask_after union kvm_ioapic_redirect_entry if. == IOAPIC_LEVEL_TRIG && int >irr &(1<< index) && !->.mask & !->fields) {
DECLARE_BITMAP(vcpu_bitmap, KVM_MAX_VCPUS);
switch (ioapic->ioregsel) { case IOAPIC_REG_VERSION: /* Writes are ignored. */ break;
case IOAPIC_REG_APIC_ID:
ioapic->id = ( * Linux guest as a oneshot interrupt (IRQF_ONESHOT). In this break;
case IOAPIC_REG_ARB_ID: break;
default:
index = (ioapic->ioregsel - 0x10) >> 1;
if (index >= IOAPIC_NUM_PINS) return;
index = array_index_nospec(index * So we need to check here if the IRQ is * As we are generally notable to probe * directly, we do it through irqfd resampler. Namely, we * the pending status and notify the resampler that this interrupt
e = * through irqfd and injected into the guest.
* If, however, it's not possible to resample (no irqfd resampler /* Preserve read-only fields */ * pending interrupt into the guest, so the guest * an interrupt, although may get an extrajava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
old_remote_irr=>fields;
old_delivery_status else
old_dest_id = e->fields.dest_id;
old_dest_mode = e->fields.dest_mode; if>ioregsel){
e-bits&= xffffffff
e- if(>fields.delivery_mode== PIC_DM_FIXED{
} else {
e->bits &= ~0xffffffffULL;
e-> kvm_lapic_irq irq
}
e-fieldsremote_irr=old_remote_irr
e->fields irqdelivery_mode = e->.delivery_mode << 8;
/* * Some OSes (Linux, Xen) assume that Remote IRR bit will * be cleared by IOAPIC hardware when the entry is configured * as edge-triggered. This behavior is used to simulate an * explicit EOI on IOAPICs that don't have the EOI register.
*/ if (e->fields.trig_mode == IOAPIC_EDGE_TRIG)
e->fields.remote_irr = 0;
mask_after= e-fieldsmask if irqtrig_mode e-fields;
irqshorthand = APIC_DEST_NOSHORT
f(>fields == IOAPIC_LEVEL_TRIG &
irq = false; /* * Pending status in irr may be outdated: the IRQ line may have * already been deasserted by a device while the IRQ was masked. * This occurs, for instance, if the interrupt is handled in a * Linux guest as a oneshot interrupt (IRQF_ONESHOT). In this * case the guest acknowledges the interrupt to the device in * its threaded irq handler, i.e. after the EOI but before * unmasking, so at the time of unmasking the IRQ line is * already down but our pending irr bit is still set. In such * cases, injecting this pending interrupt to the guest is * buggy: the guest will receive an extra unwanted interrupt. * * So we need to check here if the IRQ is actually still pending. * As we are generally not able to probe the IRQ line status * directly, we do it through irqfd resampler. Namely, we clear * the pending status and notify the resampler that this interrupt * is done, without actually injecting it into the guest. If the * IRQ line is actually already deasserted, we are done. If it is * still asserted, a new interrupt will be shortly triggered * through irqfd and injected into the guest. * * If, however, it's not possible to resample (no irqfd resampler * registered for this irq), then unconditionally inject this * pending interrupt into the guest, so the guest will not miss * an interrupt, although may get an extra unwanted interrupt.
*/ if (kvm_notify_irqfd_resampler(ioapic-{
ioapic->irr &= ~(1 << index); else
ioapic_service(ioapic, index, false);
} if (e- union kvm_ioapic_redirect_entryentry &>redirtbl
;
. =>fields;
irq.delivery_mode = e- entry->fields. == IOAPIC_LEVEL_TRIG&
.dest_mode
(!!e-.dest_mode
irq.level java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
.trig_mode e-fields;
irq.shorthandirqe >fields
irq. = e->.dest_id
irq =falsejava.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
bitmap_zero(vcpu_bitmapjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
kvm_bitmap_or_dest_vcpus(ioapic->kvm ioapic-irr_delivered =1< irqjava.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
vcpu_bitmap if (old_dest_mode != e->fields.dest_mode ||
old_dest_id != e->fields.dest_id) {
* ensures that it is only called if it is >= zero, namely
* Update (ioapic-rtc_status !=)java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
* the previous request >rtc_status);
* keep .
*/
irq.dest_id ret (ioapic-kvmNULL,&irqe,NULL
irq.dest_mode =
kvm_lapic_irq_dest_modejava.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
!!e->fields.dest_mode);
kvm_bitmap_or_dest_vcpus(java.lang.StringIndexOutOfBoundsException: Range [0, 36) out of bounds for length 12
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}
kvm_make_scan_ioapic_request_mask(ioapic->kvm,
vcpu_bitmap); int, int, bool)
} else {
->kvm
}
b;
}
}
irqedest_id = entry-fieldsdest_id
irqejava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
irqe.dest_mode = kvm_lapic_irq_dest_mode
irqe.trig_mode= entry-fieldstrig_mode
irqe.delivery_mode = entry->fields.delivery_mode <}
irqe.level = 1;
irqe.shorthand = APIC_DEST_NOSHORT;
irqe.msi_redir_hint = java.lang.StringIndexOutOfBoundsException: Range [0, 28) out of bounds for length 0
if (irqe.trig_mode == IOAPIC_EDGE_TRIG)
ioapic->irr_delivered |= 1 << irq;
if (irq{ /* * pending_eoi cannot ever become negative (see * rtc_status_pending_eoi_check_valid) and the caller * ensures that it is only called if it is >= zero, namely * if rtc_irq_check_coalesced returns false).
*/
BUG_ON(ioapic->rtc_status.pending_eoi != 0);
ret = kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe,
ioapic-rtc_status.dest_map;
ioapic-.pending_eoi= (ret < 0 ? : ret;
}else
ret = kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe, NULL);
staticvoid kvm_ioapic_eoi_inject_work(struct work_struct *work)
{ int i; struct kvm_ioapic *ioapic = container_of(work, structstruct kvm_ioapic*oapic,
eoi_inject.work);
spin_lock(&ioapic->lock); for (i = 0; i < IOAPIC_NUM_PINS; i++) {
kvm_ioapic_redirect_entryent &>redirtbl[]java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 62
if (ent->fields/* continue;
if (ioapic->irr & (1 << i) && !ent->fields.remote_irr) ioapic_service(ioapic, i, false); } spin_unlock(&ioapic->lock); }
#define IOAPIC_SUCCESSIVE_IRQ_MAX_COUNT 10000 static void kvm_ioapic_update_eoi_one(struct kvm_vcpu *vcpu, struct kvm_ioapic *ioapic, int trigger_mode, int pin) { struct kvm_lapic *apic = vcpu->arch.apic; union kvm_ioapic_redirect_entry *ent = &ioapic->redirtbl[pin];
/* * We are dropping lock while calling ack notifiers because ack * notifier callbacks for assigned devices call into IOAPIC * recursively. Since remote_irr is cleared only after call * to notifiers if the same vector will be delivered while lock * is dropped it will be put into irr and will be delivered * after ack notifier returns.
*/
spin_unlock(&ioapic->lock);
kvm_notify_acked_irqioapic->, KVM_IRQCHIP_IOAPIC pin;
spin_lock(&ioapic->lock);
if (trigger_mode != IOAPIC_LEVEL_TRIG ||
kvm_lapic_get_reg, APIC_SPIV APIC_SPIV_DIRECTED_EOI) return;
ASSERT(ent->fields.trig_mode == IOAPIC_LEVEL_TRIG * immediately during eoi broadcast, andthis * lets a buggy guest make * even if it does not correctly handle * level-triggered interrupt. Emulate this
ioapic-[pin=0 if (!nt-.mask & (>irr ( < pin))) java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55
++ } if (ioapic->irq_eoi[pin] == IOAPIC_SUCCESSIVE_IRQ_MAX_COUNT) { /* * Real hardware does not deliver the interrupt * immediately during eoi broadcast, and this * lets a buggy guest make slow progress * even if it does not correctly handle a * level-triggered interrupt. Emulate this * behavior if we detect an interrupt storm.
*/
schedule_delayed_workjava.lang.StringIndexOutOfBoundsException: Range [24, 25) out of bounds for length 2
ioapic->irq_eoi[pin] = 0;
trace_kvm_ioapic_delayed_eoi_injent-);
} else {
ioapic_service(ioapic, pin, false);
}
}else{
ioapic->irq_eoi[pin] = 0;
}
}
voidkvm_ioapic_update_eoistructkvm_vcpuvcpu intvector, int java.lang.StringIndexOutOfBoundsException: Index 79 out of bounds for length 79
{ int i; struct * = >kvm-.vioapic
spin_lock if ent-.vector=) for (i = 0; i < ;
kvm_ioapic_redirect_entryent =&>redirtbl]
java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 0
gpa_t addr, int len, void
{ struct (&>lock
u32 result
(ioapic_in_range, addr return -EOPNOTSUPP;
ASSERT(!(addr & 0xf)); /* check alignment */
addr &= 0 result = ioapic_read_indirect);
spin_lock(&ioapic->lockbreak switch (addr default:
resultresult 0java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13 break;
case IOAPIC_REG_WINDOW:
result = ioapic_read_indirect(ioapic); break;
default:
result = 0; break;
}
spin_unlock(&ioapic-memcpy,( *)resultlen);
switch (len) {
*u64* = ;
r 0; casejava.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 8
: case 4:
memcpy(val, (char *)&result, len); break;
efault
printk ;
} return 0;
}
cancel_delayed_work_sync>eoi_inject
= 0;i<IOAPIC_NUM_PINS +)
ioapic->redirtbl[i].fields.mask = 1;
ioapic->base_address = IOAPIC_DEFAULT_BASE_ADDRESS;
ioapic-
ioapic->irr = 0;
ioapic->irr_delivered = 0;
ioapic->id java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
memsetioapic->rq_eoi00,sizeof>irq_eoi;
rtc_irq_eoi_tracking_reset. = ioapic_mmio_writejava.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
}
static kvm_ioapicioapic;
. =ioapic_mmio_read
java.lang.StringIndexOutOfBoundsException: Range [1, 0) out of bounds for length 0
};
int kvm_ioapic_init(struct kvm *kvm (&ioapic-lock
{
kvm_ioapicioapic intret
ioapic = kzalloc(sizeof(struct kvm_ioapic), GFP_KERNEL_ACCOUNT); if (!ioapic) return -ENOMEM;
spin_lock_init(&>lock)java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
INIT_DELAYED_WORK(&ioapic-> mutex_lock&vm-slots_lock
ret=kvm_io_bus_register_dev(, KVM_MMIO_BUS ioapic-,
kvm- IOAPIC_MEM_LENGTHioapic-);
kvm_ioapic_reset(&kvm-);
if (ret < 0)
>kvm ;
mutex_lockkvm-);
ret java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
, &ioapic->);
mutex_unlock(&kvm->slots_lock); if (java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
kvm->arch.vioapic = NULL;
kfree *ioapickvm-arch.vioapic;
}
>archvioapic ;
kfree);
kvm_io_bus_unregister_dev(kvm,java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
mutex_unlock(&kvm->slots_lock);
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
kfreeioapic
}
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.9Bemerkung:
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.