mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-25 13:43:55 +08:00
KVM: Define a new interface kvm_intr_is_single_vcpu()
This patch defines a new interface kvm_intr_is_single_vcpu(), which can returns whether the interrupt is for single-CPU or not. It is used by VT-d PI, since now we only support single-CPU interrupts, For lowest-priority interrupts, if user configures it via /proc/irq or uses irqbalance to make it single-CPU, we can use PI to deliver the interrupts to it. Full functionality of lowest-priority support will be added later. Signed-off-by: Feng Wu <feng.wu@intel.com> Reviewed-by: Alex Williamson <alex.williamson@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
ebbfc76536
commit
8feb4a04dc
@ -1241,4 +1241,7 @@ int x86_set_memory_region(struct kvm *kvm,
|
|||||||
bool kvm_vcpu_is_reset_bsp(struct kvm_vcpu *vcpu);
|
bool kvm_vcpu_is_reset_bsp(struct kvm_vcpu *vcpu);
|
||||||
bool kvm_vcpu_is_bsp(struct kvm_vcpu *vcpu);
|
bool kvm_vcpu_is_bsp(struct kvm_vcpu *vcpu);
|
||||||
|
|
||||||
|
bool kvm_intr_is_single_vcpu(struct kvm *kvm, struct kvm_lapic_irq *irq,
|
||||||
|
struct kvm_vcpu **dest_vcpu);
|
||||||
|
|
||||||
#endif /* _ASM_X86_KVM_HOST_H */
|
#endif /* _ASM_X86_KVM_HOST_H */
|
||||||
|
@ -297,6 +297,33 @@ out:
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool kvm_intr_is_single_vcpu(struct kvm *kvm, struct kvm_lapic_irq *irq,
|
||||||
|
struct kvm_vcpu **dest_vcpu)
|
||||||
|
{
|
||||||
|
int i, r = 0;
|
||||||
|
struct kvm_vcpu *vcpu;
|
||||||
|
|
||||||
|
if (kvm_intr_is_single_vcpu_fast(kvm, irq, dest_vcpu))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
kvm_for_each_vcpu(i, vcpu, kvm) {
|
||||||
|
if (!kvm_apic_present(vcpu))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!kvm_apic_match_dest(vcpu, NULL, irq->shorthand,
|
||||||
|
irq->dest_id, irq->dest_mode))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (++r == 2)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*dest_vcpu = vcpu;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r == 1;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(kvm_intr_is_single_vcpu);
|
||||||
|
|
||||||
#define IOAPIC_ROUTING_ENTRY(irq) \
|
#define IOAPIC_ROUTING_ENTRY(irq) \
|
||||||
{ .gsi = irq, .type = KVM_IRQ_ROUTING_IRQCHIP, \
|
{ .gsi = irq, .type = KVM_IRQ_ROUTING_IRQCHIP, \
|
||||||
.u.irqchip = { .irqchip = KVM_IRQCHIP_IOAPIC, .pin = (irq) } }
|
.u.irqchip = { .irqchip = KVM_IRQCHIP_IOAPIC, .pin = (irq) } }
|
||||||
|
@ -755,6 +755,65 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool kvm_intr_is_single_vcpu_fast(struct kvm *kvm, struct kvm_lapic_irq *irq,
|
||||||
|
struct kvm_vcpu **dest_vcpu)
|
||||||
|
{
|
||||||
|
struct kvm_apic_map *map;
|
||||||
|
bool ret = false;
|
||||||
|
struct kvm_lapic *dst = NULL;
|
||||||
|
|
||||||
|
if (irq->shorthand)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
|
map = rcu_dereference(kvm->arch.apic_map);
|
||||||
|
|
||||||
|
if (!map)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (irq->dest_mode == APIC_DEST_PHYSICAL) {
|
||||||
|
if (irq->dest_id == 0xFF)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (irq->dest_id >= ARRAY_SIZE(map->phys_map))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
dst = map->phys_map[irq->dest_id];
|
||||||
|
if (dst && kvm_apic_present(dst->vcpu))
|
||||||
|
*dest_vcpu = dst->vcpu;
|
||||||
|
else
|
||||||
|
goto out;
|
||||||
|
} else {
|
||||||
|
u16 cid;
|
||||||
|
unsigned long bitmap = 1;
|
||||||
|
int i, r = 0;
|
||||||
|
|
||||||
|
if (!kvm_apic_logical_map_valid(map))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
apic_logical_id(map, irq->dest_id, &cid, (u16 *)&bitmap);
|
||||||
|
|
||||||
|
if (cid >= ARRAY_SIZE(map->logical_map))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
for_each_set_bit(i, &bitmap, 16) {
|
||||||
|
dst = map->logical_map[cid][i];
|
||||||
|
if (++r == 2)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dst && kvm_apic_present(dst->vcpu))
|
||||||
|
*dest_vcpu = dst->vcpu;
|
||||||
|
else
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = true;
|
||||||
|
out:
|
||||||
|
rcu_read_unlock();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add a pending IRQ into lapic.
|
* Add a pending IRQ into lapic.
|
||||||
* Return 1 if successfully added and 0 if discarded.
|
* Return 1 if successfully added and 0 if discarded.
|
||||||
|
@ -168,4 +168,6 @@ bool kvm_apic_pending_eoi(struct kvm_vcpu *vcpu, int vector);
|
|||||||
|
|
||||||
void wait_lapic_expire(struct kvm_vcpu *vcpu);
|
void wait_lapic_expire(struct kvm_vcpu *vcpu);
|
||||||
|
|
||||||
|
bool kvm_intr_is_single_vcpu_fast(struct kvm *kvm, struct kvm_lapic_irq *irq,
|
||||||
|
struct kvm_vcpu **dest_vcpu);
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user