Commit 24bb1811 authored by Oliver Upton's avatar Oliver Upton
Browse files

Merge branch kvm-arm64/mpam-ni into kvmarm/next



* kvm-arm64/mpam-ni:
  : Hiding FEAT_MPAM from KVM guests, courtesy of James Morse + Joey Gouly
  :
  : Fix a longstanding bug where FEAT_MPAM was accidentally exposed to KVM
  : guests + the EL2 trap configuration was not explicitly configured. As
  : part of this, bring in skeletal support for initialising the MPAM CPU
  : context so KVM can actually set traps for its guests.
  :
  : Be warned -- if this series leads to boot failures on your system,
  : you're running on turd firmware.
  :
  : As an added bonus (that builds upon the infrastructure added by the MPAM
  : series), allow userspace to configure CTR_EL0.L1Ip, courtesy of Shameer
  : Kolothum.
  KVM: arm64: Make L1Ip feature in CTR_EL0 writable from userspace
  KVM: arm64: selftests: Test ID_AA64PFR0.MPAM isn't completely ignored
  KVM: arm64: Disable MPAM visibility by default and ignore VMM writes
  KVM: arm64: Add a macro for creating filtered sys_reg_descs entries
  KVM: arm64: Fix missing traps of guest accesses to the MPAM registers
  arm64: cpufeature: discover CPU support for MPAM
  arm64: head.S: Initialise MPAM EL2 registers and disable traps
  arm64/sysreg: Convert existing MPAM sysregs and add the remaining entries

Signed-off-by: default avatarOliver Upton <oliver.upton@linux.dev>
parents 7ccd615b e9b57d7f
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -152,6 +152,8 @@ infrastructure:
     +------------------------------+---------+---------+
     | DIT                          | [51-48] |    y    |
     +------------------------------+---------+---------+
     | MPAM                         | [43-40] |    n    |
     +------------------------------+---------+---------+
     | SVE                          | [35-32] |    y    |
     +------------------------------+---------+---------+
     | GIC                          | [27-24] |    n    |
+1 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ struct cpuinfo_arm64 {
	u64		reg_revidr;
	u64		reg_gmid;
	u64		reg_smidr;
	u64		reg_mpamidr;

	u64		reg_id_aa64dfr0;
	u64		reg_id_aa64dfr1;
+5 −0
Original line number Diff line number Diff line
@@ -60,6 +60,11 @@ cpucap_is_possible(const unsigned int cap)
		return IS_ENABLED(CONFIG_ARM64_WORKAROUND_REPEAT_TLBI);
	case ARM64_WORKAROUND_SPECULATIVE_SSBS:
		return IS_ENABLED(CONFIG_ARM64_ERRATUM_3194386);
	case ARM64_MPAM:
		/*
		 * KVM MPAM support doesn't rely on the host kernel supporting MPAM.
		*/
		return true;
	}

	return true;
+17 −0
Original line number Diff line number Diff line
@@ -612,6 +612,13 @@ static inline bool id_aa64pfr1_sme(u64 pfr1)
	return val > 0;
}

static inline bool id_aa64pfr0_mpam(u64 pfr0)
{
	u32 val = cpuid_feature_extract_unsigned_field(pfr0, ID_AA64PFR0_EL1_MPAM_SHIFT);

	return val > 0;
}

static inline bool id_aa64pfr1_mte(u64 pfr1)
{
	u32 val = cpuid_feature_extract_unsigned_field(pfr1, ID_AA64PFR1_EL1_MTE_SHIFT);
@@ -838,6 +845,16 @@ static inline bool system_supports_poe(void)
		alternative_has_cap_unlikely(ARM64_HAS_S1POE);
}

static __always_inline bool system_supports_mpam(void)
{
	return alternative_has_cap_unlikely(ARM64_MPAM);
}

static __always_inline bool system_supports_mpam_hcr(void)
{
	return alternative_has_cap_unlikely(ARM64_MPAM_HCR);
}

int do_emulate_mrs(struct pt_regs *regs, u32 sys_reg, u32 rt);
bool try_emulate_mrs(struct pt_regs *regs, u32 isn);

+14 −0
Original line number Diff line number Diff line
@@ -220,6 +220,19 @@
	msr	spsr_el2, x0
.endm

.macro __init_el2_mpam
	/* Memory Partitioning And Monitoring: disable EL2 traps */
	mrs	x1, id_aa64pfr0_el1
	ubfx	x0, x1, #ID_AA64PFR0_EL1_MPAM_SHIFT, #4
	cbz	x0, .Lskip_mpam_\@		// skip if no MPAM
	msr_s	SYS_MPAM2_EL2, xzr		// use the default partition
						// and disable lower traps
	mrs_s	x0, SYS_MPAMIDR_EL1
	tbz	x0, #MPAMIDR_EL1_HAS_HCR_SHIFT, .Lskip_mpam_\@	// skip if no MPAMHCR reg
	msr_s	SYS_MPAMHCR_EL2, xzr		// clear TRAP_MPAMIDR_EL1 -> EL2
.Lskip_mpam_\@:
.endm

/**
 * Initialize EL2 registers to sane values. This should be called early on all
 * cores that were booted in EL2. Note that everything gets initialised as
@@ -237,6 +250,7 @@
	__init_el2_stage2
	__init_el2_gicv3
	__init_el2_hstr
	__init_el2_mpam
	__init_el2_nvhe_idregs
	__init_el2_cptr
	__init_el2_fgt
Loading