arch/arm64/kvm/hyp/nvhe/sys_regs.c

Source file repositories/reference/linux-study-clean/arch/arm64/kvm/hyp/nvhe/sys_regs.c

File Facts

System
Linux kernel
Corpus path
arch/arm64/kvm/hyp/nvhe/sys_regs.c
Extension
.c
Size
17546 bytes
Lines
616
Domain
Architecture Layer
Bucket
arch/arm64
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

struct pvm_ftr_bits {
	bool		sign;
	u8		shift;
	u8		width;
	u8		max_val;
	bool (*vm_supported)(const struct kvm *kvm);
};

#define __MAX_FEAT_FUNC(id, fld, max, func, sgn)				\
	{									\
		.sign = sgn,							\
		.shift = id##_##fld##_SHIFT,					\
		.width = id##_##fld##_WIDTH,					\
		.max_val = id##_##fld##_##max,					\
		.vm_supported = func,						\
	}

#define MAX_FEAT_FUNC(id, fld, max, func)					\
	__MAX_FEAT_FUNC(id, fld, max, func, id##_##fld##_SIGNED)

#define MAX_FEAT(id, fld, max)							\
	MAX_FEAT_FUNC(id, fld, max, NULL)

#define MAX_FEAT_ENUM(id, fld, max)						\
	__MAX_FEAT_FUNC(id, fld, max, NULL, false)

#define FEAT_END {	.width = 0,	}

static bool vm_has_ptrauth(const struct kvm *kvm)
{
	if (!IS_ENABLED(CONFIG_ARM64_PTR_AUTH))
		return false;

	return (cpus_have_final_cap(ARM64_HAS_ADDRESS_AUTH) ||
		cpus_have_final_cap(ARM64_HAS_GENERIC_AUTH)) &&
		kvm_vcpu_has_feature(kvm, KVM_ARM_VCPU_PTRAUTH_GENERIC);
}

static bool vm_has_sve(const struct kvm *kvm)
{
	return system_supports_sve() && kvm_vcpu_has_feature(kvm, KVM_ARM_VCPU_SVE);
}

/*
 * Definitions for features to be allowed or restricted for protected guests.
 *
 * Each field in the masks represents the highest supported value for the
 * feature. If a feature field is not present, it is not supported. Moreover,
 * these are used to generate the guest's view of the feature registers.
 *
 * The approach for protected VMs is to at least support features that are:
 * - Needed by common Linux distributions (e.g., floating point)
 * - Trivial to support, e.g., supporting the feature does not introduce or
 * require tracking of additional state in KVM
 * - Cannot be trapped or prevent the guest from using anyway
 */

static const struct pvm_ftr_bits pvmid_aa64pfr0[] = {
	MAX_FEAT(ID_AA64PFR0_EL1, EL0, IMP),
	MAX_FEAT(ID_AA64PFR0_EL1, EL1, IMP),
	MAX_FEAT(ID_AA64PFR0_EL1, EL2, IMP),
	MAX_FEAT(ID_AA64PFR0_EL1, EL3, IMP),
	MAX_FEAT(ID_AA64PFR0_EL1, FP, FP16),
	MAX_FEAT(ID_AA64PFR0_EL1, AdvSIMD, FP16),
	MAX_FEAT(ID_AA64PFR0_EL1, GIC, IMP),
	MAX_FEAT_FUNC(ID_AA64PFR0_EL1, SVE, IMP, vm_has_sve),
	MAX_FEAT(ID_AA64PFR0_EL1, RAS, IMP),
	MAX_FEAT(ID_AA64PFR0_EL1, DIT, IMP),
	MAX_FEAT(ID_AA64PFR0_EL1, CSV2, IMP),
	MAX_FEAT(ID_AA64PFR0_EL1, CSV3, IMP),
	FEAT_END
};

static const struct pvm_ftr_bits pvmid_aa64pfr1[] = {
	MAX_FEAT(ID_AA64PFR1_EL1, BT, IMP),
	MAX_FEAT(ID_AA64PFR1_EL1, SSBS, SSBS2),
	MAX_FEAT_ENUM(ID_AA64PFR1_EL1, MTE_frac, NI),
	FEAT_END
};

static const struct pvm_ftr_bits pvmid_aa64pfr2[] = {
	MAX_FEAT(ID_AA64PFR2_EL1, GCIE, NI),
	FEAT_END
};

static const struct pvm_ftr_bits pvmid_aa64mmfr0[] = {
	MAX_FEAT_ENUM(ID_AA64MMFR0_EL1, PARANGE, 40),
	MAX_FEAT_ENUM(ID_AA64MMFR0_EL1, ASIDBITS, 16),
	MAX_FEAT(ID_AA64MMFR0_EL1, BIGEND, IMP),
	MAX_FEAT(ID_AA64MMFR0_EL1, SNSMEM, IMP),

Annotation

Implementation Notes