arch/x86/kvm/vmx/posted_intr.c
Source file repositories/reference/linux-study-clean/arch/x86/kvm/vmx/posted_intr.c
File Facts
- System
- Linux kernel
- Corpus path
arch/x86/kvm/vmx/posted_intr.c- Extension
.c- Size
- 10236 bytes
- Lines
- 320
- Domain
- Architecture Layer
- Bucket
- arch/x86
- Inferred role
- Architecture Layer: implementation source
- Status
- source implementation candidate
Why This File Exists
CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kvm_host.hlinux/kvm_irqfd.hasm/irq_remapping.hasm/cpu.hlapic.hirq.hposted_intr.htrace.hvmx.htdx.h
Detected Declarations
function pi_try_set_controlfunction vmx_vcpu_pi_loadfunction vmx_can_use_vtd_pifunction pi_enable_wakeup_handlerfunction vmx_needs_pi_wakeupfunction vmx_vcpu_pi_putfunction pi_wakeup_handlerfunction pi_init_cpufunction pi_apicv_pre_state_restorefunction pi_has_pending_interruptfunction vmx_pi_start_bypassfunction vmx_pi_update_irte
Annotated Snippet
// SPDX-License-Identifier: GPL-2.0-only
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/kvm_host.h>
#include <linux/kvm_irqfd.h>
#include <asm/irq_remapping.h>
#include <asm/cpu.h>
#include "lapic.h"
#include "irq.h"
#include "posted_intr.h"
#include "trace.h"
#include "vmx.h"
#include "tdx.h"
/*
* Maintain a per-CPU list of vCPUs that need to be awakened by wakeup_handler()
* when a WAKEUP_VECTOR interrupted is posted. vCPUs are added to the list when
* the vCPU is scheduled out and is blocking (e.g. in HLT) with IRQs enabled.
* The vCPUs posted interrupt descriptor is updated at the same time to set its
* notification vector to WAKEUP_VECTOR, so that posted interrupt from devices
* wake the target vCPUs. vCPUs are removed from the list and the notification
* vector is reset when the vCPU is scheduled in.
*/
static DEFINE_PER_CPU(struct list_head, wakeup_vcpus_on_cpu);
/*
* Protect the per-CPU list with a per-CPU spinlock to handle task migration.
* When a blocking vCPU is awakened _and_ migrated to a different pCPU, the
* ->sched_in() path will need to take the vCPU off the list of the _previous_
* CPU. IRQs must be disabled when taking this lock, otherwise deadlock will
* occur if a wakeup IRQ arrives and attempts to acquire the lock.
*/
static DEFINE_PER_CPU(raw_spinlock_t, wakeup_vcpus_on_cpu_lock);
#define PI_LOCK_SCHED_OUT SINGLE_DEPTH_NESTING
static struct pi_desc *vcpu_to_pi_desc(struct kvm_vcpu *vcpu)
{
return &(to_vt(vcpu)->pi_desc);
}
static int pi_try_set_control(struct pi_desc *pi_desc, u64 *pold, u64 new)
{
/*
* PID.ON can be set at any time by a different vCPU or by hardware,
* e.g. a device. PID.control must be written atomically, and the
* update must be retried with a fresh snapshot an ON change causes
* the cmpxchg to fail.
*/
if (!try_cmpxchg64(&pi_desc->control, pold, new))
return -EBUSY;
return 0;
}
void vmx_vcpu_pi_load(struct kvm_vcpu *vcpu, int cpu)
{
struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu);
struct vcpu_vt *vt = to_vt(vcpu);
struct pi_desc old, new;
unsigned long flags;
unsigned int dest;
/*
* To simplify hot-plug and dynamic toggling of APICv, keep PI.NDST and
* PI.SN up-to-date even if there is no assigned device or if APICv is
* deactivated due to a dynamic inhibit bit, e.g. for Hyper-V's SyncIC.
*/
if (!enable_apicv || !lapic_in_kernel(vcpu))
return;
/*
* If the vCPU wasn't on the wakeup list and wasn't migrated, then the
* full update can be skipped as neither the vector nor the destination
* needs to be changed. Clear SN even if there is no assigned device,
* again for simplicity.
*/
if (pi_desc->nv != POSTED_INTR_WAKEUP_VECTOR && vcpu->cpu == cpu) {
if (pi_test_and_clear_sn(pi_desc))
goto after_clear_sn;
return;
}
local_irq_save(flags);
/*
* If the vCPU was waiting for wakeup, remove the vCPU from the wakeup
* list of the _previous_ pCPU, which will not be the same as the
* current pCPU if the task was migrated.
Annotation
- Immediate include surface: `linux/kvm_host.h`, `linux/kvm_irqfd.h`, `asm/irq_remapping.h`, `asm/cpu.h`, `lapic.h`, `irq.h`, `posted_intr.h`, `trace.h`.
- Detected declarations: `function pi_try_set_control`, `function vmx_vcpu_pi_load`, `function vmx_can_use_vtd_pi`, `function pi_enable_wakeup_handler`, `function vmx_needs_pi_wakeup`, `function vmx_vcpu_pi_put`, `function pi_wakeup_handler`, `function pi_init_cpu`, `function pi_apicv_pre_state_restore`, `function pi_has_pending_interrupt`.
- Atlas domain: Architecture Layer / arch/x86.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.