drivers/hv/mshv_eventfd.c

Source file repositories/reference/linux-study-clean/drivers/hv/mshv_eventfd.c

File Facts

System
Linux kernel
Corpus path
drivers/hv/mshv_eventfd.c
Extension
.c
Size
21203 bytes
Lines
854
Domain
Driver Families
Bucket
drivers/hv
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.

Dependency Surface

Detected Declarations

Annotated Snippet

if (mian->irq_ack_gsi == gsi) {
			mian->irq_acked(mian);
			acked = true;
		}
	}
	rcu_read_unlock();

	return acked;
}

#if IS_ENABLED(CONFIG_ARM64)
static inline bool hv_should_clear_interrupt(enum hv_interrupt_type type)
{
	return false;
}
#elif IS_ENABLED(CONFIG_X86_64)
static inline bool hv_should_clear_interrupt(enum hv_interrupt_type type)
{
	return type == HV_X64_INTERRUPT_TYPE_EXTINT;
}
#endif

static void mshv_irqfd_resampler_ack(struct mshv_irq_ack_notifier *mian)
{
	struct mshv_irqfd_resampler *resampler;
	struct mshv_partition *partition;
	struct mshv_irqfd *irqfd;
	int idx;

	resampler = container_of(mian, struct mshv_irqfd_resampler,
				 rsmplr_notifier);
	partition = resampler->rsmplr_partn;

	idx = srcu_read_lock(&partition->pt_irq_srcu);

	hlist_for_each_entry_srcu(irqfd, &resampler->rsmplr_irqfd_list,
				 irqfd_resampler_hnode,
				 srcu_read_lock_held(&partition->pt_irq_srcu)) {
		if (hv_should_clear_interrupt(irqfd->irqfd_lapic_irq.lapic_control.interrupt_type))
			hv_call_clear_virtual_interrupt(partition->pt_id);

		eventfd_signal(irqfd->irqfd_resamplefd);
	}

	srcu_read_unlock(&partition->pt_irq_srcu, idx);
}

#if IS_ENABLED(CONFIG_X86_64)
static bool
mshv_vp_irq_vector_injected(union hv_vp_register_page_interrupt_vectors iv,
			    u32 vector)
{
	int i;

	for (i = 0; i < iv.vector_count; i++) {
		if (iv.vector[i] == vector)
			return true;
	}

	return false;
}

static int mshv_vp_irq_try_set_vector(struct mshv_vp *vp, u32 vector)
{
	union hv_vp_register_page_interrupt_vectors iv, new_iv;

	iv = vp->vp_register_page->interrupt_vectors;
	new_iv = iv;

	if (mshv_vp_irq_vector_injected(iv, vector))
		return 0;

	if (iv.vector_count >= HV_VP_REGISTER_PAGE_MAX_VECTOR_COUNT)
		return -ENOSPC;

	new_iv.vector[new_iv.vector_count++] = vector;

	if (!try_cmpxchg(&vp->vp_register_page->interrupt_vectors.as_uint64,
			 &iv.as_uint64, new_iv.as_uint64))
		return -EAGAIN;

	return 0;
}

static int mshv_vp_irq_set_vector(struct mshv_vp *vp, u32 vector)
{
	int ret;

	do {
		ret = mshv_vp_irq_try_set_vector(vp, vector);

Annotation

Implementation Notes