arch/x86/kernel/cpu/vmware.c

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

File Facts

System
Linux kernel
Corpus path
arch/x86/kernel/cpu/vmware.c
Extension
.c
Size
15177 bytes
Lines
596
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

struct vmware_steal_time {
	union {
		u64 clock;	/* stolen time counter in units of vtsc */
		struct {
			/* only for little-endian */
			u32 clock_low;
			u32 clock_high;
		};
	};
	u64 reserved[7];
};

static unsigned long vmware_tsc_khz __ro_after_init;
static u8 vmware_hypercall_mode     __ro_after_init;

unsigned long vmware_hypercall_slow(unsigned long cmd,
				    unsigned long in1, unsigned long in3,
				    unsigned long in4, unsigned long in5,
				    u32 *out1, u32 *out2, u32 *out3,
				    u32 *out4, u32 *out5)
{
	unsigned long out0, rbx, rcx, rdx, rsi, rdi;

	switch (vmware_hypercall_mode) {
	case CPUID_VMWARE_FEATURES_ECX_VMCALL:
		asm_inline volatile ("vmcall"
				: "=a" (out0), "=b" (rbx), "=c" (rcx),
				"=d" (rdx), "=S" (rsi), "=D" (rdi)
				: "a" (VMWARE_HYPERVISOR_MAGIC),
				"b" (in1),
				"c" (cmd),
				"d" (in3),
				"S" (in4),
				"D" (in5)
				: "cc", "memory");
		break;
	case CPUID_VMWARE_FEATURES_ECX_VMMCALL:
		asm_inline volatile ("vmmcall"
				: "=a" (out0), "=b" (rbx), "=c" (rcx),
				"=d" (rdx), "=S" (rsi), "=D" (rdi)
				: "a" (VMWARE_HYPERVISOR_MAGIC),
				"b" (in1),
				"c" (cmd),
				"d" (in3),
				"S" (in4),
				"D" (in5)
				: "cc", "memory");
		break;
	default:
		asm_inline volatile ("movw %[port], %%dx; inl (%%dx), %%eax"
				: "=a" (out0), "=b" (rbx), "=c" (rcx),
				"=d" (rdx), "=S" (rsi), "=D" (rdi)
				: [port] "i" (VMWARE_HYPERVISOR_PORT),
				"a" (VMWARE_HYPERVISOR_MAGIC),
				"b" (in1),
				"c" (cmd),
				"d" (in3),
				"S" (in4),
				"D" (in5)
				: "cc", "memory");
		break;
	}

	if (out1)
		*out1 = rbx;
	if (out2)
		*out2 = rcx;
	if (out3)
		*out3 = rdx;
	if (out4)
		*out4 = rsi;
	if (out5)
		*out5 = rdi;

	return out0;
}

static inline int __vmware_platform(void)
{
	u32 eax, ebx, ecx;

	eax = vmware_hypercall3(VMWARE_CMD_GETVERSION, 0, &ebx, &ecx);
	return eax != UINT_MAX && ebx == VMWARE_HYPERVISOR_MAGIC;
}

static unsigned long vmware_get_tsc_khz(void)
{
	return vmware_tsc_khz;
}

Annotation

Implementation Notes