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.
- 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/io.hlinux/kernel.hlinux/mm.hlinux/slab.hlinux/vmalloc.hlinux/hyperv.hlinux/random.hlinux/clockchips.hlinux/delay.hlinux/interrupt.hlinux/export.hclocksource/hyperv_timer.hasm/mshyperv.hlinux/set_memory.hhyperv_vmbus.h
Detected Declarations
function hv_initfunction hv_post_messagefunction hv_alloc_pagefunction hv_free_pagefunction hv_synic_allocfunction for_each_present_cpufunction hv_synic_freefunction for_each_present_cpufunction hv_hyp_synic_enable_regsfunction hv_hyp_synic_enable_interruptsfunction hv_para_synic_enable_regsfunction hv_para_synic_enable_interruptsfunction hv_synic_initfunction hv_hyp_synic_disable_regsfunction hv_hyp_synic_disable_interruptsfunction hv_para_synic_disable_regsfunction hv_para_synic_disable_interruptsfunction __hv_synic_event_pendingfunction hv_synic_event_pendingfunction hv_pick_new_cpufunction for_each_cpu_wrapfunction hv_synic_cleanupfunction list_for_each_entry
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
- Immediate include surface: `linux/io.h`, `linux/kernel.h`, `linux/mm.h`, `linux/slab.h`, `linux/vmalloc.h`, `linux/hyperv.h`, `linux/random.h`, `linux/clockchips.h`.
- Detected declarations: `function hv_init`, `function hv_post_message`, `function hv_alloc_page`, `function hv_free_page`, `function hv_synic_alloc`, `function for_each_present_cpu`, `function hv_synic_free`, `function for_each_present_cpu`, `function hv_hyp_synic_enable_regs`, `function hv_hyp_synic_enable_interrupts`.
- Atlas domain: Driver Families / drivers/hv.
- Implementation status: integration 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.