2 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
4 #include <linux/kvm_host.h>
6 #include <asm/irq_remapping.h>
74 if (
pi_desc->
nv != POSTED_INTR_WAKEUP_VECTOR && vcpu->cpu == cpu) {
84 local_irq_save(
flags);
91 if (
pi_desc->
nv == POSTED_INTR_WAKEUP_VECTOR) {
92 raw_spin_lock(&per_cpu(wakeup_vcpus_on_cpu_lock, vcpu->cpu));
94 raw_spin_unlock(&per_cpu(wakeup_vcpus_on_cpu_lock, vcpu->cpu));
97 dest = cpu_physical_id(cpu);
99 dest = (dest << 8) & 0xFF00;
116 new.nv = POSTED_INTR_VECTOR;
119 local_irq_restore(
flags);
129 smp_mb__after_atomic();
139 irq_remapping_cap(IRQ_POSTING_CAP);
153 local_irq_save(
flags);
155 raw_spin_lock(&per_cpu(wakeup_vcpus_on_cpu_lock, vcpu->cpu));
157 &per_cpu(wakeup_vcpus_on_cpu, vcpu->cpu));
158 raw_spin_unlock(&per_cpu(wakeup_vcpus_on_cpu_lock, vcpu->cpu));
160 WARN(
pi_desc->
sn,
"PI descriptor SN field set before blocking");
166 new.nv = POSTED_INTR_WAKEUP_VECTOR;
178 __apic_send_IPI_self(POSTED_INTR_WAKEUP_VECTOR);
180 local_irq_restore(
flags);
220 int cpu = smp_processor_id();
221 struct list_head *wakeup_list = &per_cpu(wakeup_vcpus_on_cpu, cpu);
222 raw_spinlock_t *spinlock = &per_cpu(wakeup_vcpus_on_cpu_lock, cpu);
225 raw_spin_lock(spinlock);
231 raw_spin_unlock(spinlock);
236 INIT_LIST_HEAD(&per_cpu(wakeup_vcpus_on_cpu, cpu));
237 raw_spin_lock_init(&per_cpu(wakeup_vcpus_on_cpu_lock, cpu));
257 if (!irq_remapping_cap(IRQ_POSTING_CAP))
273 uint32_t guest_irq,
bool set)
275 struct kvm_kernel_irq_routing_entry *e;
276 struct kvm_irq_routing_table *irq_rt;
277 struct kvm_lapic_irq irq;
278 struct kvm_vcpu *vcpu;
279 struct vcpu_data vcpu_info;
285 idx = srcu_read_lock(&kvm->irq_srcu);
286 irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu);
287 if (guest_irq >= irq_rt->nr_rt_entries ||
288 hlist_empty(&irq_rt->map[guest_irq])) {
289 pr_warn_once(
"no route for guest_irq %u/%u (broken user space?)\n",
290 guest_irq, irq_rt->nr_rt_entries);
294 hlist_for_each_entry(e, &irq_rt->map[guest_irq], link) {
295 if (e->type != KVM_IRQ_ROUTING_MSI)
315 !kvm_irq_is_postable(&irq)) {
320 ret = irq_set_vcpu_affinity(host_irq, NULL);
323 "failed to back to remapped mode, irq: %u\n",
332 vcpu_info.vector = irq.vector;
334 trace_kvm_pi_irte_update(host_irq, vcpu->vcpu_id, e->gsi,
335 vcpu_info.vector, vcpu_info.pi_desc_addr, set);
338 ret = irq_set_vcpu_affinity(host_irq, &vcpu_info);
340 ret = irq_set_vcpu_affinity(host_irq, NULL);
343 printk(KERN_INFO
"%s: failed to update PI IRTE\n",
351 srcu_read_unlock(&kvm->irq_srcu, idx);
#define irqchip_in_kernel(k)
void kvm_set_msi_irq(struct kvm *kvm, struct kvm_kernel_irq_routing_entry *e, struct kvm_lapic_irq *irq)
bool kvm_intr_is_single_vcpu(struct kvm *kvm, struct kvm_lapic_irq *irq, struct kvm_vcpu **dest_vcpu)
bool kvm_make_all_cpus_request(struct kvm *kvm, unsigned int req)
bool kvm_vcpu_wake_up(struct kvm_vcpu *vcpu)
static bool lapic_in_kernel(struct kvm_vcpu *vcpu)
bool pi_has_pending_interrupt(struct kvm_vcpu *vcpu)
static bool vmx_needs_pi_wakeup(struct kvm_vcpu *vcpu)
static struct pi_desc * vcpu_to_pi_desc(struct kvm_vcpu *vcpu)
void vmx_pi_start_assignment(struct kvm *kvm)
void vmx_vcpu_pi_load(struct kvm_vcpu *vcpu, int cpu)
void __init pi_init_cpu(int cpu)
static int pi_try_set_control(struct pi_desc *pi_desc, u64 *pold, u64 new)
static void pi_enable_wakeup_handler(struct kvm_vcpu *vcpu)
void vmx_vcpu_pi_put(struct kvm_vcpu *vcpu)
void pi_wakeup_handler(void)
int vmx_pi_update_irte(struct kvm *kvm, unsigned int host_irq, uint32_t guest_irq, bool set)
static bool vmx_can_use_vtd_pi(struct kvm *kvm)
static DEFINE_PER_CPU(struct list_head, wakeup_vcpus_on_cpu)
static bool pi_test_sn(struct pi_desc *pi_desc)
static bool pi_test_and_clear_sn(struct pi_desc *pi_desc)
static void pi_set_on(struct pi_desc *pi_desc)
static bool pi_is_pir_empty(struct pi_desc *pi_desc)
static void pi_set_sn(struct pi_desc *pi_desc)
static bool pi_test_on(struct pi_desc *pi_desc)
struct list_head pi_wakeup_list
bool vmx_interrupt_blocked(struct kvm_vcpu *vcpu)
static bool vmx_can_use_ipiv(struct kvm_vcpu *vcpu)
static __always_inline struct vcpu_vmx * to_vmx(struct kvm_vcpu *vcpu)
bool __read_mostly enable_apicv
bool noinstr kvm_arch_has_assigned_device(struct kvm *kvm)