Commit a0ec2b82 authored by Marc Zyngier's avatar Marc Zyngier
Browse files

KVM: arm64: nv: Snapshot S1 ASID tagging information during walk



We currently completely ignore any sort of ASID tagging during a S1
walk, as AT doesn't care about it.

However, such information is required if we are going to create
anything that looks like a TLB from this walk.

Let's capture it both the nG and ASID information while walking
the page tables.

Reviewed-by: default avatarOliver Upton <oliver.upton@linux.dev>
Link: https://lore.kernel.org/r/20250514103501.2225951-5-maz@kernel.org


Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
parent 34fa9dec
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -274,6 +274,8 @@ struct s1_walk_result {
			u64	pa;
			s8	level;
			u8	APTable;
			bool	nG;
			u16	asid;
			bool	UXNTable;
			bool	PXNTable;
			bool	uwxn;
+27 −0
Original line number Diff line number Diff line
@@ -414,6 +414,33 @@ static int walk_s1(struct kvm_vcpu *vcpu, struct s1_walk_info *wi,
	wr->pa = desc & GENMASK(47, va_bottom);
	wr->pa |= va & GENMASK_ULL(va_bottom - 1, 0);

	wr->nG = (wi->regime != TR_EL2) && (desc & PTE_NG);
	if (wr->nG) {
		u64 asid_ttbr, tcr;

		switch (wi->regime) {
		case TR_EL10:
			tcr = vcpu_read_sys_reg(vcpu, TCR_EL1);
			asid_ttbr = ((tcr & TCR_A1) ?
				     vcpu_read_sys_reg(vcpu, TTBR1_EL1) :
				     vcpu_read_sys_reg(vcpu, TTBR0_EL1));
			break;
		case TR_EL20:
			tcr = vcpu_read_sys_reg(vcpu, TCR_EL2);
			asid_ttbr = ((tcr & TCR_A1) ?
				     vcpu_read_sys_reg(vcpu, TTBR1_EL2) :
				     vcpu_read_sys_reg(vcpu, TTBR0_EL2));
			break;
		default:
			BUG();
		}

		wr->asid = FIELD_GET(TTBR_ASID_MASK, asid_ttbr);
		if (!kvm_has_feat_enum(vcpu->kvm, ID_AA64MMFR0_EL1, ASIDBITS, 16) ||
		    !(tcr & TCR_ASID16))
			wr->asid &= GENMASK(7, 0);
	}

	return 0;

addrsz: