drivers/xen/events/events_2l.c
Source file repositories/reference/linux-study-clean/drivers/xen/events/events_2l.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/xen/events/events_2l.c- Extension
.c- Size
- 11003 bytes
- Lines
- 385
- Domain
- Driver Families
- Bucket
- drivers/xen
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/linkage.hlinux/interrupt.hlinux/irq.hasm/sync_bitops.hasm/xen/hypercall.hasm/xen/hypervisor.hxen/xen.hxen/xen-ops.hxen/events.hxen/interface/xen.hxen/interface/event_channel.hevents_internal.h
Detected Declarations
function evtchn_2l_max_channelsfunction evtchn_2l_removefunction evtchn_2l_bind_to_cpufunction evtchn_2l_clear_pendingfunction evtchn_2l_set_pendingfunction evtchn_2l_is_pendingfunction evtchn_2l_maskfunction evtchn_2l_unmaskfunction pendingfunction active_evtchnsfunction evtchn_2l_handle_eventsfunction xen_debug_interruptfunction for_each_online_cpufunction evtchn_2l_resumefunction evtchn_2l_percpu_deinitfunction xen_evtchn_2l_init
Annotated Snippet
if (unlikely(evtchn_pending && xen_hvm_domain())) {
sync_set_bit(port, BM(&s->evtchn_mask[0]));
do_hypercall = 1;
}
}
/* Slow path (hypercall) if this is a non-local port or if this is
* an hvm domain and an event is pending (hvm domains don't have
* their own implementation of irq_enable). */
if (do_hypercall) {
struct evtchn_unmask unmask = { .port = port };
(void)HYPERVISOR_event_channel_op(EVTCHNOP_unmask, &unmask);
} else {
struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu);
/*
* The following is basically the equivalent of
* 'hw_resend_irq'. Just like a real IO-APIC we 'lose
* the interrupt edge' if the channel is masked.
*/
if (evtchn_pending &&
!sync_test_and_set_bit(port / BITS_PER_EVTCHN_WORD,
BM(&vcpu_info->evtchn_pending_sel)))
vcpu_info->evtchn_upcall_pending = 1;
}
put_cpu();
}
static DEFINE_PER_CPU(unsigned int, current_word_idx);
static DEFINE_PER_CPU(unsigned int, current_bit_idx);
/*
* Mask out the i least significant bits of w
*/
#define MASK_LSBS(w, i) (w & ((~((xen_ulong_t)0UL)) << i))
static inline xen_ulong_t active_evtchns(unsigned int cpu,
struct shared_info *sh,
unsigned int idx)
{
return sh->evtchn_pending[idx] &
per_cpu(cpu_evtchn_mask, cpu)[idx] &
~sh->evtchn_mask[idx];
}
/*
* Search the CPU's pending events bitmasks. For each one found, map
* the event number to an irq, and feed it into do_IRQ() for handling.
*
* Xen uses a two-level bitmap to speed searching. The first level is
* a bitset of words which contain pending event bits. The second
* level is a bitset of pending events themselves.
*/
static void evtchn_2l_handle_events(unsigned cpu, struct evtchn_loop_ctrl *ctrl)
{
int irq;
xen_ulong_t pending_words;
xen_ulong_t pending_bits;
int start_word_idx, start_bit_idx;
int word_idx, bit_idx;
int i;
struct shared_info *s = HYPERVISOR_shared_info;
struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu);
evtchn_port_t evtchn;
/* Timer interrupt has highest priority. */
irq = irq_evtchn_from_virq(cpu, VIRQ_TIMER, &evtchn);
if (irq != -1) {
word_idx = evtchn / BITS_PER_LONG;
bit_idx = evtchn % BITS_PER_LONG;
if (active_evtchns(cpu, s, word_idx) & (1ULL << bit_idx))
generic_handle_irq(irq);
}
/*
* Master flag must be cleared /before/ clearing
* selector flag. xchg_xen_ulong must contain an
* appropriate barrier.
*/
pending_words = xchg_xen_ulong(&vcpu_info->evtchn_pending_sel, 0);
start_word_idx = __this_cpu_read(current_word_idx);
start_bit_idx = __this_cpu_read(current_bit_idx);
word_idx = start_word_idx;
for (i = 0; pending_words != 0; i++) {
xen_ulong_t words;
Annotation
- Immediate include surface: `linux/linkage.h`, `linux/interrupt.h`, `linux/irq.h`, `asm/sync_bitops.h`, `asm/xen/hypercall.h`, `asm/xen/hypervisor.h`, `xen/xen.h`, `xen/xen-ops.h`.
- Detected declarations: `function evtchn_2l_max_channels`, `function evtchn_2l_remove`, `function evtchn_2l_bind_to_cpu`, `function evtchn_2l_clear_pending`, `function evtchn_2l_set_pending`, `function evtchn_2l_is_pending`, `function evtchn_2l_mask`, `function evtchn_2l_unmask`, `function pending`, `function active_evtchns`.
- Atlas domain: Driver Families / drivers/xen.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.