arch/x86/kernel/cpu/mshyperv.c

Source file repositories/reference/linux-study-clean/arch/x86/kernel/cpu/mshyperv.c

File Facts

System
Linux kernel
Corpus path
arch/x86/kernel/cpu/mshyperv.c
Extension
.c
Size
22746 bytes
Lines
812
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.

Dependency Surface

Detected Declarations

Annotated Snippet

if (hv_is_sint_msr(reg)) {
			union hv_synic_sint sint = { .as_uint64 = value };

			sint.proxy = hv_para_sint_proxy;
			native_wrmsrq(reg, sint.as_uint64);
		}
	} else {
		native_wrmsrq(reg, value);
	}
}
EXPORT_SYMBOL_GPL(hv_set_non_nested_msr);

/*
 * Enable or disable proxying synthetic interrupts
 * to the paravisor.
 */
void hv_para_set_sint_proxy(bool enable)
{
	hv_para_sint_proxy = enable;
}

/*
 * Get the SynIC register value from the paravisor.
 */
u64 hv_para_get_synic_register(unsigned int reg)
{
	if (WARN_ON(!ms_hyperv.paravisor_present || !hv_is_synic_msr(reg)))
		return ~0ULL;
	return native_read_msr(reg);
}

/*
 * Set the SynIC register value with the paravisor.
 */
void hv_para_set_synic_register(unsigned int reg, u64 val)
{
	if (WARN_ON(!ms_hyperv.paravisor_present || !hv_is_synic_msr(reg)))
		return;
	native_write_msr(reg, val);
}

u64 hv_get_msr(unsigned int reg)
{
	if (hv_nested)
		reg = hv_get_nested_msr(reg);

	return hv_get_non_nested_msr(reg);
}
EXPORT_SYMBOL_GPL(hv_get_msr);

void hv_set_msr(unsigned int reg, u64 value)
{
	if (hv_nested)
		reg = hv_get_nested_msr(reg);

	hv_set_non_nested_msr(reg, value);
}
EXPORT_SYMBOL_GPL(hv_set_msr);

static void (*mshv_handler)(void);
static void (*vmbus_handler)(void);
static void (*hv_stimer0_handler)(void);
static void (*hv_kexec_handler)(void);
static void (*hv_crash_handler)(struct pt_regs *regs);

DEFINE_IDTENTRY_SYSVEC(sysvec_hyperv_callback)
{
	struct pt_regs *old_regs = set_irq_regs(regs);

	inc_irq_stat(HYPERVISOR_CALLBACK);
	if (mshv_handler)
		mshv_handler();

	if (vmbus_handler)
		vmbus_handler();

	add_interrupt_randomness(HYPERVISOR_CALLBACK_VECTOR);

	if (ms_hyperv.hints & HV_DEPRECATING_AEOI_RECOMMENDED)
		apic_eoi();

	set_irq_regs(old_regs);
}

void hv_setup_mshv_handler(void (*handler)(void))
{
	mshv_handler = handler;
}

void hv_setup_vmbus_handler(void (*handler)(void))

Annotation

Implementation Notes