arch/x86/kvm/hyperv.c
Source file repositories/reference/linux-study-clean/arch/x86/kvm/hyperv.c
File Facts
- System
- Linux kernel
- Corpus path
arch/x86/kvm/hyperv.c- Extension
.c- Size
- 78968 bytes
- Lines
- 2931
- Domain
- Architecture Layer
- Bucket
- arch/x86
- Inferred role
- Architecture Layer: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- 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
x86.hlapic.hioapic.hcpuid.hhyperv.hmmu.hxen.hlinux/cpu.hlinux/kvm_host.hlinux/highmem.hlinux/sched/cputime.hlinux/spinlock.hlinux/eventfd.hasm/apicdef.hasm/mshyperv.htrace/events/kvm.htrace.hirq.hfpu.h
Detected Declarations
struct kvm_hv_hcallfunction synic_read_sintfunction synic_get_sint_vectorfunction synic_has_vector_connectedfunction synic_has_vector_auto_eoifunction synic_update_vectorfunction synic_set_sintfunction kvm_hv_notify_acked_sintfunction synic_exitfunction synic_set_msrfunction kvm_hv_is_syndbg_enabledfunction kvm_hv_syndbg_complete_userspacefunction syndbg_exitfunction syndbg_set_msrfunction syndbg_get_msrfunction synic_get_msrfunction synic_set_irqfunction kvm_hv_synic_set_irqfunction kvm_hv_synic_send_eoifunction kvm_hv_set_sint_gsifunction kvm_hv_irq_routing_updatefunction hlist_for_each_entryfunction synic_initfunction get_time_ref_counterfunction stimer_mark_pendingfunction stimer_cleanupfunction stimer_timer_callbackfunction stimer_startfunction stimer_set_configfunction stimer_set_countfunction stimer_get_configfunction stimer_get_countfunction synic_deliver_msgfunction stimer_send_msgfunction stimer_notify_directfunction stimer_expirationfunction kvm_hv_process_stimersfunction kvm_hv_vcpu_uninitfunction kvm_hv_assist_page_enabledfunction kvm_hv_get_assist_pagefunction stimer_prepare_msgfunction stimer_initfunction kvm_hv_vcpu_initfunction kvm_hv_activate_synicfunction kvm_hv_msr_partition_widefunction kvm_hv_msr_get_crash_datafunction kvm_hv_msr_get_crash_ctlfunction kvm_hv_msr_set_crash_ctl
Annotated Snippet
struct kvm_hv_hcall {
/* Hypercall input data */
u64 param;
u64 ingpa;
u64 outgpa;
u16 code;
u16 var_cnt;
u16 rep_cnt;
u16 rep_idx;
bool fast;
bool rep;
sse128_t xmm[HV_HYPERCALL_MAX_XMM_REGISTERS];
/*
* Current read offset when KVM reads hypercall input data gradually,
* either offset in bytes from 'ingpa' for regular hypercalls or the
* number of already consumed 'XMM halves' for 'fast' hypercalls.
*/
union {
gpa_t data_offset;
int consumed_xmm_halves;
};
};
static int kvm_hv_get_hc_data(struct kvm *kvm, struct kvm_hv_hcall *hc,
u16 orig_cnt, u16 cnt_cap, u64 *data)
{
/*
* Preserve the original count when ignoring entries via a "cap", KVM
* still needs to validate the guest input (though the non-XMM path
* punts on the checks).
*/
u16 cnt = min(orig_cnt, cnt_cap);
int i, j;
if (hc->fast) {
/*
* Each XMM holds two sparse banks, but do not count halves that
* have already been consumed for hypercall parameters.
*/
if (orig_cnt > 2 * HV_HYPERCALL_MAX_XMM_REGISTERS - hc->consumed_xmm_halves)
return HV_STATUS_INVALID_HYPERCALL_INPUT;
for (i = 0; i < cnt; i++) {
j = i + hc->consumed_xmm_halves;
if (j % 2)
data[i] = sse128_hi(hc->xmm[j / 2]);
else
data[i] = sse128_lo(hc->xmm[j / 2]);
}
return 0;
}
return kvm_read_guest(kvm, hc->ingpa + hc->data_offset, data,
cnt * sizeof(*data));
}
static u64 kvm_get_sparse_vp_set(struct kvm *kvm, struct kvm_hv_hcall *hc,
u64 *sparse_banks)
{
if (hc->var_cnt > HV_MAX_SPARSE_VCPU_BANKS)
return -EINVAL;
/* Cap var_cnt to ignore banks that cannot contain a legal VP index. */
return kvm_hv_get_hc_data(kvm, hc, hc->var_cnt, KVM_HV_MAX_SPARSE_VCPU_SET_BITS,
sparse_banks);
}
static int kvm_hv_get_tlb_flush_entries(struct kvm *kvm, struct kvm_hv_hcall *hc, u64 entries[])
{
return kvm_hv_get_hc_data(kvm, hc, hc->rep_cnt, hc->rep_cnt, entries);
}
static void hv_tlb_flush_enqueue(struct kvm_vcpu *vcpu,
struct kvm_vcpu_hv_tlb_flush_fifo *tlb_flush_fifo,
u64 *entries, int count)
{
struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
u64 flush_all_entry = KVM_HV_TLB_FLUSHALL_ENTRY;
if (!hv_vcpu)
return;
spin_lock(&tlb_flush_fifo->write_lock);
/*
* All entries should fit on the fifo leaving one free for 'flush all'
* entry in case another request comes in. In case there's not enough
* space, just put 'flush all' entry there.
Annotation
- Immediate include surface: `x86.h`, `lapic.h`, `ioapic.h`, `cpuid.h`, `hyperv.h`, `mmu.h`, `xen.h`, `linux/cpu.h`.
- Detected declarations: `struct kvm_hv_hcall`, `function synic_read_sint`, `function synic_get_sint_vector`, `function synic_has_vector_connected`, `function synic_has_vector_auto_eoi`, `function synic_update_vector`, `function synic_set_sint`, `function kvm_hv_notify_acked_sint`, `function synic_exit`, `function synic_set_msr`.
- Atlas domain: Architecture Layer / arch/x86.
- Implementation status: integration implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- 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.