Commit 1c07f35f authored by Marc Zyngier's avatar Marc Zyngier
Browse files

Merge branch kvm-arm64/vtcr into kvmarm-master/next



* kvm-arm64/vtcr:
  : .
  : VTCR_EL2 conversion to the configuration-driven RESx framework,
  : fixing a couple of UXN/PXN/XN bugs in the process.
  : .
  KVM: arm64: nv: Return correct RES0 bits for FGT registers
  KVM: arm64: Always populate FGT masks at boot time
  KVM: arm64: Honor UX/PX attributes for EL2 S1 mappings
  KVM: arm64: Convert VTCR_EL2 to config-driven sanitisation
  KVM: arm64: Account for RES1 bits in DECLARE_FEAT_MAP() and co
  arm64: Convert VTCR_EL2 to sysreg infratructure
  arm64: Convert ID_AA64MMFR0_EL1.TGRAN{4,16,64}_2 to UnsignedEnum
  KVM: arm64: Invert KVM_PGTABLE_WALK_HANDLE_FAULT to fix pKVM walkers
  KVM: arm64: Don't blindly set set PSTATE.PAN on guest exit
  KVM: arm64: nv: Respect stage-2 write permssion when setting stage-1 AF
  KVM: arm64: Remove unused vcpu_{clear,set}_wfx_traps()
  KVM: arm64: Remove unused parameter in synchronize_vcpu_pstate()
  KVM: arm64: Remove extra argument for __pvkm_host_{share,unshare}_hyp()
  KVM: arm64: Inject UNDEF for a register trap without accessor
  KVM: arm64: Copy FGT traps to unprotected pKVM VCPU on VCPU load
  KVM: arm64: Fix EL2 S1 XN handling for hVHE setups
  KVM: arm64: gic: Check for vGICv3 when clearing TWI

Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
parents 31c70b97 2eb80a2e
Loading
Loading
Loading
Loading
+12 −40
Original line number Diff line number Diff line
@@ -124,37 +124,7 @@
#define TCR_EL2_MASK	(TCR_EL2_TG0_MASK | TCR_EL2_SH0_MASK | \
			 TCR_EL2_ORGN0_MASK | TCR_EL2_IRGN0_MASK)

/* VTCR_EL2 Registers bits */
#define VTCR_EL2_DS		TCR_EL2_DS
#define VTCR_EL2_RES1		(1U << 31)
#define VTCR_EL2_HD		(1 << 22)
#define VTCR_EL2_HA		(1 << 21)
#define VTCR_EL2_PS_SHIFT	TCR_EL2_PS_SHIFT
#define VTCR_EL2_PS_MASK	TCR_EL2_PS_MASK
#define VTCR_EL2_TG0_MASK	TCR_TG0_MASK
#define VTCR_EL2_TG0_4K		TCR_TG0_4K
#define VTCR_EL2_TG0_16K	TCR_TG0_16K
#define VTCR_EL2_TG0_64K	TCR_TG0_64K
#define VTCR_EL2_SH0_MASK	TCR_SH0_MASK
#define VTCR_EL2_SH0_INNER	TCR_SH0_INNER
#define VTCR_EL2_ORGN0_MASK	TCR_ORGN0_MASK
#define VTCR_EL2_ORGN0_WBWA	TCR_ORGN0_WBWA
#define VTCR_EL2_IRGN0_MASK	TCR_IRGN0_MASK
#define VTCR_EL2_IRGN0_WBWA	TCR_IRGN0_WBWA
#define VTCR_EL2_SL0_SHIFT	6
#define VTCR_EL2_SL0_MASK	(3 << VTCR_EL2_SL0_SHIFT)
#define VTCR_EL2_T0SZ_MASK	0x3f
#define VTCR_EL2_VS_SHIFT	19
#define VTCR_EL2_VS_8BIT	(0 << VTCR_EL2_VS_SHIFT)
#define VTCR_EL2_VS_16BIT	(1 << VTCR_EL2_VS_SHIFT)

#define VTCR_EL2_T0SZ(x)	TCR_T0SZ(x)

/*
 * We configure the Stage-2 page tables to always restrict the IPA space to be
 * 40 bits wide (T0SZ = 24).  Systems with a PARange smaller than 40 bits are
 * not known to exist and will break with this configuration.
 *
 * The VTCR_EL2 is configured per VM and is initialised in kvm_init_stage2_mmu.
 *
 * Note that when using 4K pages, we concatenate two first level page tables
@@ -162,9 +132,6 @@
 *
 */

#define VTCR_EL2_COMMON_BITS	(VTCR_EL2_SH0_INNER | VTCR_EL2_ORGN0_WBWA | \
				 VTCR_EL2_IRGN0_WBWA | VTCR_EL2_RES1)

/*
 * VTCR_EL2:SL0 indicates the entry level for Stage2 translation.
 * Interestingly, it depends on the page size.
@@ -196,30 +163,35 @@
 */
#ifdef CONFIG_ARM64_64K_PAGES

#define VTCR_EL2_TGRAN			VTCR_EL2_TG0_64K
#define VTCR_EL2_TGRAN			64K
#define VTCR_EL2_TGRAN_SL0_BASE		3UL

#elif defined(CONFIG_ARM64_16K_PAGES)

#define VTCR_EL2_TGRAN			VTCR_EL2_TG0_16K
#define VTCR_EL2_TGRAN			16K
#define VTCR_EL2_TGRAN_SL0_BASE		3UL

#else	/* 4K */

#define VTCR_EL2_TGRAN			VTCR_EL2_TG0_4K
#define VTCR_EL2_TGRAN			4K
#define VTCR_EL2_TGRAN_SL0_BASE		2UL

#endif

#define VTCR_EL2_LVLS_TO_SL0(levels)	\
	((VTCR_EL2_TGRAN_SL0_BASE - (4 - (levels))) << VTCR_EL2_SL0_SHIFT)
	FIELD_PREP(VTCR_EL2_SL0, (VTCR_EL2_TGRAN_SL0_BASE - (4 - (levels))))
#define VTCR_EL2_SL0_TO_LVLS(sl0)	\
	((sl0) + 4 - VTCR_EL2_TGRAN_SL0_BASE)
#define VTCR_EL2_LVLS(vtcr)		\
	VTCR_EL2_SL0_TO_LVLS(((vtcr) & VTCR_EL2_SL0_MASK) >> VTCR_EL2_SL0_SHIFT)
	VTCR_EL2_SL0_TO_LVLS(FIELD_GET(VTCR_EL2_SL0, (vtcr)))

#define VTCR_EL2_FLAGS	(SYS_FIELD_PREP_ENUM(VTCR_EL2, SH0, INNER)	    | \
			 SYS_FIELD_PREP_ENUM(VTCR_EL2, ORGN0, WBWA)	    | \
			 SYS_FIELD_PREP_ENUM(VTCR_EL2, IRGN0, WBWA)	    | \
			 SYS_FIELD_PREP_ENUM(VTCR_EL2, TG0, VTCR_EL2_TGRAN) | \
			 VTCR_EL2_RES1)

#define VTCR_EL2_FLAGS			(VTCR_EL2_COMMON_BITS | VTCR_EL2_TGRAN)
#define VTCR_EL2_IPA(vtcr)		(64 - ((vtcr) & VTCR_EL2_T0SZ_MASK))
#define VTCR_EL2_IPA(vtcr)		(64 - FIELD_GET(VTCR_EL2_T0SZ, (vtcr)))

/*
 * ARM VMSAv8-64 defines an algorithm for finding the translation table
+0 −16
Original line number Diff line number Diff line
@@ -120,22 +120,6 @@ static inline unsigned long *vcpu_hcr(struct kvm_vcpu *vcpu)
	return (unsigned long *)&vcpu->arch.hcr_el2;
}

static inline void vcpu_clear_wfx_traps(struct kvm_vcpu *vcpu)
{
	vcpu->arch.hcr_el2 &= ~HCR_TWE;
	if (atomic_read(&vcpu->arch.vgic_cpu.vgic_v3.its_vpe.vlpi_count) ||
	    vcpu->kvm->arch.vgic.nassgireq)
		vcpu->arch.hcr_el2 &= ~HCR_TWI;
	else
		vcpu->arch.hcr_el2 |= HCR_TWI;
}

static inline void vcpu_set_wfx_traps(struct kvm_vcpu *vcpu)
{
	vcpu->arch.hcr_el2 |= HCR_TWE;
	vcpu->arch.hcr_el2 |= HCR_TWI;
}

static inline unsigned long vcpu_get_vsesr(struct kvm_vcpu *vcpu)
{
	return vcpu->arch.vsesr_el2;
+1 −0
Original line number Diff line number Diff line
@@ -638,6 +638,7 @@ struct fgt_masks {
	u64		mask;
	u64		nmask;
	u64		res0;
	u64		res1;
};

extern struct fgt_masks hfgrtr_masks;
+5 −3
Original line number Diff line number Diff line
@@ -88,6 +88,8 @@ typedef u64 kvm_pte_t;
#define KVM_PTE_LEAF_ATTR_HI_SW		GENMASK(58, 55)

#define KVM_PTE_LEAF_ATTR_HI_S1_XN	BIT(54)
#define KVM_PTE_LEAF_ATTR_HI_S1_UXN	BIT(54)
#define KVM_PTE_LEAF_ATTR_HI_S1_PXN	BIT(53)

#define KVM_PTE_LEAF_ATTR_HI_S2_XN	GENMASK(54, 53)

@@ -293,8 +295,8 @@ typedef bool (*kvm_pgtable_force_pte_cb_t)(u64 addr, u64 end,
 *					children.
 * @KVM_PGTABLE_WALK_SHARED:		Indicates the page-tables may be shared
 *					with other software walkers.
 * @KVM_PGTABLE_WALK_HANDLE_FAULT:	Indicates the page-table walk was
 *					invoked from a fault handler.
 * @KVM_PGTABLE_WALK_IGNORE_EAGAIN:	Don't terminate the walk early if
 *					the walker returns -EAGAIN.
 * @KVM_PGTABLE_WALK_SKIP_BBM_TLBI:	Visit and update table entries
 *					without Break-before-make's
 *					TLB invalidation.
@@ -307,7 +309,7 @@ enum kvm_pgtable_walk_flags {
	KVM_PGTABLE_WALK_TABLE_PRE		= BIT(1),
	KVM_PGTABLE_WALK_TABLE_POST		= BIT(2),
	KVM_PGTABLE_WALK_SHARED			= BIT(3),
	KVM_PGTABLE_WALK_HANDLE_FAULT		= BIT(4),
	KVM_PGTABLE_WALK_IGNORE_EAGAIN		= BIT(4),
	KVM_PGTABLE_WALK_SKIP_BBM_TLBI		= BIT(5),
	KVM_PGTABLE_WALK_SKIP_CMO		= BIT(6),
};
+2 −2
Original line number Diff line number Diff line
@@ -91,7 +91,8 @@
 */
#define pstate_field(op1, op2)		((op1) << Op1_shift | (op2) << Op2_shift)
#define PSTATE_Imm_shift		CRm_shift
#define SET_PSTATE(x, r)		__emit_inst(0xd500401f | PSTATE_ ## r | ((!!x) << PSTATE_Imm_shift))
#define ENCODE_PSTATE(x, r)		(0xd500401f | PSTATE_ ## r | ((!!x) << PSTATE_Imm_shift))
#define SET_PSTATE(x, r)		__emit_inst(ENCODE_PSTATE(x, r))

#define PSTATE_PAN			pstate_field(0, 4)
#define PSTATE_UAO			pstate_field(0, 3)
@@ -516,7 +517,6 @@
#define SYS_TTBR1_EL2			sys_reg(3, 4, 2, 0, 1)
#define SYS_TCR_EL2			sys_reg(3, 4, 2, 0, 2)
#define SYS_VTTBR_EL2			sys_reg(3, 4, 2, 1, 0)
#define SYS_VTCR_EL2			sys_reg(3, 4, 2, 1, 2)

#define SYS_HAFGRTR_EL2			sys_reg(3, 4, 3, 1, 6)
#define SYS_SPSR_EL2			sys_reg(3, 4, 4, 0, 0)
Loading