arch/x86/kvm/regs.h

Source file repositories/reference/linux-study-clean/arch/x86/kvm/regs.h

File Facts

System
Linux kernel
Corpus path
arch/x86/kvm/regs.h
Extension
.h
Size
12763 bytes
Lines
424
Domain
Architecture Layer
Bucket
arch/x86
Inferred role
Architecture Layer: implementation source
Status
source 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

#ifndef ARCH_X86_KVM_REGS_H
#define ARCH_X86_KVM_REGS_H

#include <linux/kvm_host.h>

#define KVM_POSSIBLE_CR0_GUEST_BITS	(X86_CR0_TS | X86_CR0_WP)
#define KVM_POSSIBLE_CR4_GUEST_BITS				  \
	(X86_CR4_PVI | X86_CR4_DE | X86_CR4_PCE | X86_CR4_OSFXSR  \
	 | X86_CR4_OSXMMEXCPT | X86_CR4_PGE | X86_CR4_TSD | X86_CR4_FSGSBASE \
	 | X86_CR4_CET)

#define X86_CR0_PDPTR_BITS    (X86_CR0_CD | X86_CR0_NW | X86_CR0_PG)
#define X86_CR4_TLBFLUSH_BITS (X86_CR4_PGE | X86_CR4_PCIDE | X86_CR4_PAE | X86_CR4_SMEP)
#define X86_CR4_PDPTR_BITS    (X86_CR4_PGE | X86_CR4_PSE | X86_CR4_PAE | X86_CR4_SMEP)

static_assert(!(KVM_POSSIBLE_CR0_GUEST_BITS & X86_CR0_PDPTR_BITS));

static inline bool is_long_mode(struct kvm_vcpu *vcpu)
{
#ifdef CONFIG_X86_64
	return !!(vcpu->arch.efer & EFER_LMA);
#else
	return false;
#endif
}

static inline bool is_64_bit_mode(struct kvm_vcpu *vcpu)
{
	int cs_db, cs_l;

	WARN_ON_ONCE(vcpu->arch.guest_state_protected);

	if (!is_long_mode(vcpu))
		return false;
	kvm_x86_call(get_cs_db_l_bits)(vcpu, &cs_db, &cs_l);
	return cs_l;
}

static inline bool is_64_bit_hypercall(struct kvm_vcpu *vcpu)
{
#ifdef CONFIG_X86_64
	/*
	 * If running with protected guest state, the CS register is not
	 * accessible. The hypercall register values will have had to been
	 * provided in 64-bit mode, so assume the guest is in 64-bit.
	 */
	return vcpu->arch.guest_state_protected || is_64_bit_mode(vcpu);
#else
	return false;
#endif
}

static __always_inline unsigned long kvm_reg_mode_mask(struct kvm_vcpu *vcpu)
{
#ifdef CONFIG_X86_64
	return is_64_bit_mode(vcpu) ? GENMASK(63, 0) : GENMASK(31, 0);
#else
	return GENMASK(31, 0);
#endif
}

#define __BUILD_KVM_GPR_ACCESSORS(lname, uname)						\
static __always_inline unsigned long kvm_##lname##_read(struct kvm_vcpu *vcpu)		\
{											\
	return vcpu->arch.regs[VCPU_REGS_##uname] & kvm_reg_mode_mask(vcpu);		\
}											\
static __always_inline unsigned long kvm_##lname##_read_raw(struct kvm_vcpu *vcpu)	\
{											\
	return vcpu->arch.regs[VCPU_REGS_##uname];					\
}											\
static __always_inline void kvm_##lname##_write_raw(struct kvm_vcpu *vcpu,		\
						    unsigned long val)			\
{											\
	vcpu->arch.regs[VCPU_REGS_##uname] = val;					\
}
#define BUILD_KVM_GPR_ACCESSORS(lname, uname)						\
static __always_inline u32 kvm_e##lname##_read(struct kvm_vcpu *vcpu)			\
{											\
	return vcpu->arch.regs[VCPU_REGS_##uname];					\
}											\
static __always_inline void kvm_e##lname##_write(struct kvm_vcpu *vcpu, u32 val)	\
{											\
	vcpu->arch.regs[VCPU_REGS_##uname] = val;					\
}											\
__BUILD_KVM_GPR_ACCESSORS(r##lname, uname)

BUILD_KVM_GPR_ACCESSORS(ax, RAX)
BUILD_KVM_GPR_ACCESSORS(bx, RBX)
BUILD_KVM_GPR_ACCESSORS(cx, RCX)
BUILD_KVM_GPR_ACCESSORS(dx, RDX)

Annotation

Implementation Notes