drivers/hv/hv.c

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

File Facts

System
Linux kernel
Corpus path
drivers/hv/hv.c
Extension
.c
Size
18279 bytes
Lines
659
Domain
Driver Families
Bucket
drivers/hv
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 (ms_hyperv.paravisor_present && hv_isolation_type_tdx()) {
			ret = hv_alloc_page(&hv_cpu->post_msg_page,
				decrypt, "post msg");
			if (ret)
				goto err;
		}

		/*
		 * If these SynIC pages are not allocated, SIEF and SIM pages
		 * are configured using what the root partition or the paravisor
		 * provides upon reading the SIEFP and SIMP registers.
		 */
		if (!ms_hyperv.paravisor_present && !hv_root_partition()) {
			ret = hv_alloc_page(&hv_cpu->hyp_synic_message_page,
				decrypt, "hypervisor SynIC msg");
			if (ret)
				goto err;
			ret = hv_alloc_page(&hv_cpu->hyp_synic_event_page,
				decrypt, "hypervisor SynIC event");
			if (ret)
				goto err;
		}

		if (vmbus_is_confidential()) {
			ret = hv_alloc_page(&hv_cpu->para_synic_message_page,
				false, "paravisor SynIC msg");
			if (ret)
				goto err;
			ret = hv_alloc_page(&hv_cpu->para_synic_event_page,
				false, "paravisor SynIC event");
			if (ret)
				goto err;
		}
	}

	return 0;

err:
	/*
	 * Any memory allocations that succeeded will be freed when
	 * the caller cleans up by calling hv_synic_free()
	 */
	return ret;
}

void hv_synic_free(void)
{
	int cpu;
	const bool encrypt = !vmbus_is_confidential();

	for_each_present_cpu(cpu) {
		struct hv_per_cpu_context *hv_cpu =
			per_cpu_ptr(hv_context.cpu_context, cpu);

		if (ms_hyperv.paravisor_present && hv_isolation_type_tdx())
			hv_free_page(&hv_cpu->post_msg_page,
				encrypt, "post msg");
		if (!ms_hyperv.paravisor_present && !hv_root_partition()) {
			hv_free_page(&hv_cpu->hyp_synic_event_page,
				encrypt, "hypervisor SynIC event");
			hv_free_page(&hv_cpu->hyp_synic_message_page,
				encrypt, "hypervisor SynIC msg");
		}
		if (vmbus_is_confidential()) {
			hv_free_page(&hv_cpu->para_synic_event_page,
				false, "paravisor SynIC event");
			hv_free_page(&hv_cpu->para_synic_message_page,
				false, "paravisor SynIC msg");
		}
	}

	kfree(hv_context.hv_numa_map);
}

/*
 * hv_hyp_synic_enable_regs - Initialize the Synthetic Interrupt Controller
 * with the hypervisor.
 *
 * Note: When MSHV is present, mshv_synic_cpu_init() intializes further
 * registers later.
 */
void hv_hyp_synic_enable_regs(unsigned int cpu)
{
	struct hv_per_cpu_context *hv_cpu =
		per_cpu_ptr(hv_context.cpu_context, cpu);
	union hv_synic_simp simp;
	union hv_synic_siefp siefp;
	union hv_synic_sint shared_sint;

	/* Setup the Synic's message page with the hypervisor. */

Annotation

Implementation Notes